Navigated to /.

Fully Managed React

Build your product, we'll take care of the rest.

Nokkio is the first full-stack React framework – from prototype to production including dev environments, build tooling, production hosting, databases, networking, data resolution, authentication, image uploads and resizing, SSR, and more.

Application code
😰
DatabaseSSRMigrationsDev EnvDeploymentsHostingBuild ConfigData fetchingData APIsCI IntegrationBackupsImage uploads
⏲️ Get started in 1 minute
No account or payment required. Run the following three commands in your terminal and begin working on your new project right away.
1 Install Nokkio CLI
/bin/bash -c "$(curl -fsSL https://nokk.io/install.sh)"
2 Create a project
nokkio create my-first-project
3 Start the dev server
cd my-first-project && nokkio dev
4 Continue learning in the docs
Not at your computer right now? Sign up for our newsletter and we'll send you a welcome email with steps on getting started.
Infrastructure included

You've configured webpack for the last time. Install the nokkio cli tool and use it to create a project, boot up your development environment, and deploy to production.

~/code/my-project nokkio create my-new-app
Setting up my-new-app
Scaffolding project
Setting up package config
Installing dependencies
my-new-app created successfully
Magic Data

Web applications require real, persisted data. Nokkio provides a magical abstraction for your application's data. Define a schema using plain JavaScript and Nokkio takes care of managing your database, the backend API, and implementing your client-side networking code.

schema.js
/** @type {import('@nokkio/schema').Config} */
module.exports = function ({ defineModel, types }) {
  const List = defineModel('List', {
    title: types.string(),
  });

  const Todo = defineModel('Todo', {
    description: types.string(),
    isComplete: types.bool(false),
  });

  List.hasMany(Todo);

  return { List, Todo };
};

Once your schema is in place, immediately begin using data into your components without writing backend code, fumbling with API keys, or managing infrastructure.

pages/index.tsx
import { usePageData } from '@nokkio/router';
import { List } from '@nokkio/magic';

export const getPageData = () => {
  return List.find({ withCounts: ['todos'] });
};

export default function Index(): JSX.Element {
  const lists = usePageData<typeof getPageData>();

  return (
    <ul>
      {lists.map((list) => (
        <li>
          {list.title} ({list.todosCount} todos)
        </li>
      ))}
    </ul>
  );
}

Mutations are supported out of the box using Nokkio's forms package. Nokkio keeps track of where your data is used, automatically refreshing just the components where that data is used.

pages/index.tsx
import { usePageData } from '@nokkio/router';
import { List } from '@nokkio/magic';
import { Input, useForm } from '@nokkio/forms';

export const getPageData = () => {
  return List.find({ withCounts: ['todos'] });
};

export default function Index(): JSX.Element {
  const lists = usePageData<typeof getPageData>();
  const { Form } = useForm(List);

  return (
    <div>
      <Form>
        <Input name="title" />
        <button>Create list</button>
      </Form>

      <ul>
        {lists.map((list) => (
          <li>
            {list.title} ({list.todosCount} todos)
          </li>
        ))}
      </ul>
    </div>
  );
}
Authentication

Adding authentication to a Nokkio application is a one-liner and built atop Nokkio's native data abstraction.

schema.js
/** @type {import('@nokkio/schema').Config} */
module.exports = function ({ defineModel, types }) {
  const User = defineModel('User', {
    username: types.string().unique(),
    password: types.password(),
  });

  const List = defineModel('List', {
    title: types.string(),
  });

  const Todo = defineModel('Todo', {
    description: types.string(),
    isComplete: types.bool(false),
  });

  User.hasMany(List);
  List.hasMany(Todo);

  User.actAsAuth();

  return { List, Todo, User };
};

When Nokkio knows which model to use for authentication, it takes care of the rest–including built-in components that make login and registration forms a breeze.

pages/login.tsx
import { useLoginForm } from '@nokkio/auth';
import { Input } from '@nokkio/forms';

export default function LoginPage(): JSX.Element {
  const { Form } = useLoginForm();

  return (
    <Form>
      <Input name="username" />
      <Input name="password" />
      <button>Login</button>
    </Form>
  );
}
Deploy in seconds

When you're ready, deploy to a production environment custom-fit for Nokkio applications. Working with a team? Connect your repository to Nokkio’s Github application and get a new deploy for every push to your main branch, and preview deploys for every pull request.

~/code/my-project nokkio deploy
Building project
Building @nokkio/magic from schema.js
Building endpoints
Running nokkio:ci
Checking for new assets
Creating deploy
Deploying assets
Activating deploy
Success! Deployed to https://my-new-app.nokk.io
Image resizing

Add an image field to your Nokkio model and get durable storage and automatic image resizing out of the box.

Endpoints

For the times when you do need backend logic, you can accept traffic to endpoints by defining a JavaScript function.

Automatic refetching

No need to manage complex local state. Nokkio knows when your data has changed and automatically refetches.

Use your favorite tools

Prefer to write TypeScript? You'll have end-to-end type safety for your data. Want to use Tailwind? Support is baked in.

Stay up to date

Subscribe to periodic updates via email from the Nokkio team.