Quickstart
In a few minutes you'll have the current Kovo starter running: a signed-in contact book over a real Drizzle database, Better Auth session handling, a guarded mutation, typed queries, styled components, tests, CI, and production build wiring.
Status: pre-v1. Kovo isn't on npm yet. Today you run it from a cloned checkout of the Kovo repository, with the generated app linked back to the local workspace packages.
1. Scaffold#
Today, use the repo-local scaffold flow:
git clone https://github.com/kovojs/kovo.git
cd kovo
pnpm install
node --experimental-transform-types packages/create-kovo/src/index.ts examples/my-app --disable-git
node scripts/link-local-kovo.mjs examples/my-app
cd examples/my-app
pnpm install --ignore-workspaceAfter packages publish, the short form becomes:
pnpm create kovo my-app
cd my-app
pnpm installUse SQLite when you want a local file-backed starter instead of the default PGlite/Postgres-shaped one:
pnpm create kovo my-app -- --dialect sqlite --experimental-sqliteThe scaffold writes src/app.tsx, src/auth.ts, src/db.ts, src/schema.ts, src/queries.ts,
src/mutations.ts, two starter components, theme/CSS files, a Vitest app test, Vite/Kovo config,
CI, .env.example, and a generated local .env with a fresh CSRF secret. The generated .env is
gitignored; replace the secret in your deployment environment before shipping.
2. Run it#
pnpm run devOpen /login and sign in with the seeded demo user. Use demo@example.com and the random
KOVO_DEMO_PASSWORD value from the generated, gitignored .env file.
The home page is a complete HTML document served from typed routes - no client framework booted, no hydration. View Source and you'll see real markup for the shell, the signed-in user, and the contact region.
3. Check it#
Run the starter's focused gates before editing:
pnpm run check
pnpm testpnpm run check is the starter's source-only quick gate. It joins format, lint, TypeScript, the
framework-owned sound-subset policy, and current-source compiler/security proof without requiring
deployment retention or writing dist. pnpm test runs the starter test through the same app
wiring. The explicit production proof is also present from day one:
npm run build:prod
npm run check:endpoint-posture
npm start4. Make the first real change#
Start with the domain data. Add a field to src/schema.ts, include it in src/queries.ts, render
it in src/components/contacts.tsx, and update src/mutations.ts if the add-contact form should
write it. That path exercises the whole starter: Drizzle schema, typed query, guarded mutation,
styled component render, and test coverage.
A normal wiring mistake fails early. For example, if contactsQuery returns id, name, email,
and company but a component tries to render a field that does not exist:
<span>{contact.phone}</span>then:
pnpm run checkreports the binding error during development instead of letting the mismatch reach production.
5. Extend the starter safely#
The starter is already an authenticated data app: schema, Better Auth session, typed query, guarded mutation, route layout, styled components, test, and production build. Extend that slice in place instead of replacing it with an empty shell.
Start with one product concept and add it through the same modules the contact book uses:
| Step | File | What changes |
|---|---|---|
| 1 | src/schema.ts |
Add the table and Kovo domain/key metadata. |
| 2 | src/db.ts |
Seed local rows or connect the real storage path. |
| 3 | src/queries.ts |
Add one typed read for the first screen. |
| 4 | src/mutations.ts |
Add one guarded write with validation and CSRF. |
| 5 | src/components/*.tsx |
Render the query and form from TSX. |
| 6 | src/app.tsx |
Register the query, mutation, route, and stylesheet. |
| 7 | src/app.test.ts |
Prove the route and mutation path. |
Keep auth central in src/auth.ts. New product mutations should import the existing CSRF config
and guard helpers instead of declaring their own auth path. Add routes near the existing / and
/login declarations in src/app.tsx, keep shared frame in layout(), and put access rules in the
route declaration rather than hiding them in component code.
Run the narrow checks before and after the change:
pnpm run check
pnpm testWhen the feature crosses data domains or relies on optimistic behavior, add a graph assertion or a
kovo explain check the same way the Commerce, CRM, and Stack Overflow examples do.
The commands you'll use daily#
kovo owns the app-facing loop: dev, check, test, build, explain, and add. The full
table lives in
Installation > The everyday commands.
Next#
- Thinking in Kovo - how components become self-describing HTML.
- Installation - prerequisites and what the scaffold sets up.
- Project structure - where the starter keeps auth, data, and route wiring.
- Examples - larger apps built from the same route/query/mutation facts.
- Commerce example - a larger authenticated storefront built the same way.
Spec & diagnostics
Typed routes and link checking: SPEC section 6.4. Strict-TypeScript sound subset as the basis for the static guarantees: SPEC section 6.6. Data-binding paths checked against query result shape: SPEC section 4.8.