Quickstart
Create a new Kizaki app, run it locally, and make your first authenticated change in under ten minutes.
This guide uses the React Router SaaS template, the default and fastest way to learn the platform.
By the end of this page, you will have:
- a Kizaki CLI install on your machine
- a scaffolded Kizaki app
- a running local development stack
- an authenticated browser session
- a generated client call going from the frontend to your server code
1. Install The CLI
# macOS (Homebrew)
brew install kizakicorp/tap/kizaki
# macOS or Linux (direct installer)
curl -fsSL https://get.kizaki.ai/install.sh | shThe public installer places the standalone kizaki binary on disk. Your first kizaki init or kizaki dev command downloads the exact matching managed runtime automatically.
2. Create A New App
kizaki init hello-kizaki
cd hello-kizaki
npm installThis gives you:
- an Inspire schema in
schema/main.inspire - server functions in
src/functions.tsas the starter file - a React Router frontend
- a committed baseline migration
3. Start The Local Stack
kizaki devThe startup sequence:
- checks the toolchain
- boots embedded Postgres
- applies committed migrations
- starts the runtime and local app
- opens browser-ready HTTP and WebSocket endpoints
When startup completes:
- keep the terminal running
- open the local app URL from the output
- treat that terminal as the control center for the app while you work
kizaki dev runs the full coordinated local environment: your schema, runtime, generated client, and browser app together.
4. Sign In Locally
The SaaS template ships with email auth enabled. In local development, use the built-in dev login flow to create a session for yourself.
Once you are logged in, the starter app shows your personal todos.
This confirms the default stack is wired correctly:
- auth is active
- the current principal is available in server code
- the generated client can call exposed functions
- the UI renders data scoped to the signed-in user
5. Create A Todo
The template already includes exposed server functions and a generated client. The initial server code looks like this:
import { getPrincipal, insert, query, select, eq } from "@kizaki/sdk";
import { Todo } from "@kizaki/schema";
/** @expose */
export async function listTodos() {
const me = getPrincipal();
return query(
select(Todo)
.fields(Todo.id, Todo.title, Todo.completed)
.where(eq(Todo.ownerId, me.id)),
);
}
/** @expose */
export async function createTodo(title: string): Promise<Todo> {
const me = getPrincipal();
const [todo] = await query(
insert(Todo)
.values({ title, ownerId: me.id })
.returning(),
);
return todo;
}From the frontend, the generated client is called directly:
import { createTodo } from "@kizaki/client";
await createTodo("Ship the first version");This is the central Kizaki loop:
- write server logic in
src/(src/functions.tsis just the default starting point) - mark it with
/** @expose */ - let the compiler generate a typed client
- call that generated client from the app
You do not need to keep all exposed functions in one file. Kizaki scans supported TypeScript source files under src/, and the generated packages refresh automatically during the local dev loop.
You do not hand-author a REST layer for this path.
6. What To Learn Next
Follow the recommended path: