---
title: "Five-minute path"
description: "From an empty folder to an app with sign-in, a database and a protected route, in four commands and twelve lines you write."
section: "getting-started"
status: "Planned for 0.3"
spec: "design-language"
canonical: "https://mainsdk.dev/docs/getting-started/five-minutes"
updated: "2026-10-28"
---

# Five-minute path

> From an empty folder to an app with sign-in, a database and a protected route, in four commands and twelve lines you write.

Status: Planned for 0.3 · Canonical: https://mainsdk.dev/docs/getting-started/five-minutes · Updated: 2026-10-28

Four commands and one file take you from an empty folder to a running app where every note belongs to the person who wrote it. You need Node 22.18 or later. No account, no keys, and nothing leaves your machine.

## 1. Set up the project

```bash
npx mainsdk init
```

```text
$ npx mainsdk init
mainsdk init · notes

  Found      empty folder · npm · Claude Code
  Wrote      main.yaml        project prj_01JC8Q4N7V3X9B2D5F6G8H0JKM
             app.ts           a fetch handler that says hello
             package.json     mainsdk as a dependency
             .gitignore       .mainsdk/
             CLAUDE.md        MainSDK rules, between markers
             agent context    .claude/ · .cursor/ · AGENTS.md
             .mcp.json        mainsdk mcp for Claude Code

  Every interface runs on a local driver. No account, no keys.

Next
  1  npx mainsdk add auth db     sign-in and a database
  2  npx mainsdk dev app.ts      run it on 127.0.0.1:3000
  3  npx mainsdk check           see what to fix before you ship
```

`init` writes `main.yaml` for you. You never write it by hand on this path.

## 2. Add sign-in and a database

```bash
npx mainsdk add auth db
```

## 3. Write the app

Replace `app.ts` with this. It is the only file you write, and it is 12 lines.

```ts
import { auth, models } from "mainsdk"
import { s } from "mainsdk/schema"

const { notes } = models({ notes: s.object({ text: s.string() }) })

export default async function fetch(req: Request) {
  const { user } = await auth.require(req)
  const mine = notes.for(user)
  if (req.method === "POST") return Response.json(await mine.create(await req.json()))
  return Response.json(await mine.list())
}
```

## 4. Run it

```bash
npx mainsdk dev app.ts
```

```text
$ npx mainsdk dev app.ts
mainsdk dev · notes · env dev

  auth       local      dev sign-in on
  db         local      .mainsdk/db/app.sqlite
  log        terminal

  No cloud calls. No provider keys. Network observe, loopback only.

Ready  http://127.0.0.1:3000 · 0.4s
  Sign in as a test user: -H "authorization: Bearer dev_ada"
  Logs: mainsdk logs --follow · Stop: Ctrl-C

12:04:31  GET   /   401   2ms   MAIN-AUTH-0001 not signed in
12:04:40  POST  /   200   6ms   ada
12:04:42  GET   /   200   3ms   ada
```

In a second terminal, ask without signing in. You get `401` with a code and the one thing to do:

```bash
curl -i http://127.0.0.1:3000/
```

Sign in as the test user `ada`, write a note and read it back. The `dev_` token works only from this machine and only under `mainsdk dev`:

```bash
curl -X POST http://127.0.0.1:3000/ -H "authorization: Bearer dev_ada" -H "content-type: application/json" -d '{"text":"hello"}'
curl http://127.0.0.1:3000/ -H "authorization: Bearer dev_ada"
curl http://127.0.0.1:3000/ -H "authorization: Bearer dev_bob"
```

`ada` sees her note. `bob` sees an empty page, because every query belongs to its owner.

## 5. Check it

```bash
npx mainsdk check
```

```text
$ npx mainsdk check
mainsdk check · notes · env dev · Main 27

  ✓ config   ✓ secrets   ✓ policy   ✓ network   ✓ auth   ✓ data

Passed · 6 gates · 0 findings · 1.2s
```

## Next

- [Existing app](https://mainsdk.dev/docs/getting-started/existing-app): add MainSDK to a project you already have.
- [Thirty-minute path](https://mainsdk.dev/docs/getting-started/thirty-minutes): the longer route, with the three ideas explained.
- [Interfaces](https://mainsdk.dev/docs/interfaces): everything else the app can use, each with a one-line happy path.
