Quickstart

Create a Beignet app, run it, and make one change you can watch take effect. This is the first page to follow when you are new to Beignet.

Alpha software: Beignet is experimental alpha software. The 0.0.x package line is for early evaluation, and APIs may change between releases.

Create an app

bun create beignet my-app
cd my-app
bun install
cp .env.example .env.local

npm create beignet@latest, pnpm create beignet, and yarn create beignet work the same way. See the CLI reference for the setup prompts and flags such as --api and --db.

There is one starter: a working full-stack app with a shadcn/Tailwind UI shell, Better Auth sign-in, sign-up, and settings pages, and a user-owned todos feature backed by contracts, use cases, and Drizzle/libSQL.

Generated apps include @beignet/cli as a dev dependency, so every command after creation runs as bun beignet <command> from the app directory.

Prepare the database

bun beignet db migrate

The initial migration ships vendored in the scaffold's drizzle/ folder, so db migrate is the only database step before the first run.

The default starter uses SQLite — nothing to install or start. If you created the app with --db postgres or --db mysql, start the database server before db migrate:

# Postgres 14+
docker run --rm -d -e POSTGRES_USER=beignet -e POSTGRES_PASSWORD=beignet -e POSTGRES_DB=beignet_test -p 5432:5432 postgres:17-alpine

# MySQL 8.0+
docker run --rm -d -e MYSQL_ROOT_PASSWORD=beignet -e MYSQL_DATABASE=beignet_test -p 3306:3306 mysql:8.4

Start the app

bun run dev

Open http://localhost:3000/sign-up and create the first account. Signing up lands on the dashboard inside the app shell. The sidebar links to Dashboard, Todos, and Settings, plus Devtools and the OpenAPI document while the app runs in development.

Todos is the feature to study: create a todo, complete it with the checkbox, delete it. It exercises contracts, use cases, ports, the typed client, React Query, and React Hook Form end to end.

Make your first change

The todo title rule lives in one Zod schema that the form, the API, and the OpenAPI document all share. Tighten it and watch all three react.

Open features/todos/schemas.ts and change CreateTodoInputSchema:

 export const CreateTodoInputSchema = z.object({
-  title: z.string().min(1).max(120),
+  title: z.string().min(3, "Give the todo at least 3 characters.").max(120),
 });

With bun run dev still running:

One schema edit changed the form, the API, and the generated docs. That is the core Beignet loop: define the shape once, let every surface consume it.

Inspect the app

bun beignet routes
bun run lint
bun beignet lint
bun beignet doctor
bun run typecheck

routes confirms which contracts are wired to route files. bun run lint runs Biome's code lint. bun run format applies Biome formatting. beignet lint checks that feature layers do not import runtime, UI, or infrastructure code in the wrong direction. doctor checks for route, OpenAPI, and resource drift. typecheck verifies that route handlers, use cases, ports, clients, and tests still agree with the contracts.

Open these files first

File or folderWhy it matters
features/todos/contracts.tsEndpoint shapes used by the server, the typed client, OpenAPI, and React helpers
features/todos/schemas.tsThe shared Zod schemas you just edited
features/todos/use-cases/Application behavior and validation
server/routes.tsCentral route registry and OpenAPI contract list
server/index.tsRuntime composition: providers, hooks, and error mapping
infra/app-ports.tsDefault runtime wiring for the app's dependency interfaces

Next, read Mental model for the vocabulary these files use, then Build your first feature to generate a second feature and follow one real change end to end. App architecture has the full folder map when you want it.