Quickstart
Go from zero to a running TypoKit API in under 5 minutes. By the end of this guide you’ll have a type-safe API server with auto-generated validation, routing, and OpenAPI docs.
Prerequisites
Section titled “Prerequisites”- Node.js 24+ — Download
- A package manager — pnpm (recommended), npm, or yarn
npm install -g pnpmnpm is included with Node.js — no extra install needed.
corepack enableCreate a New Project
Section titled “Create a New Project”-
Scaffold your app
Run the TypoKit initializer to create a new project:
Terminal window pnpm dlx @typokit/cli scaffold init my-app --server native --db rawTerminal window npx @typokit/cli scaffold init my-app --server native --db rawTerminal window yarn dlx @typokit/cli scaffold init my-app --server native --db rawYou should see output like:
✔ Created my-app/✔ Initialized package.json✔ Installed dependencies✔ Generated project structureYour TypoKit project is ready!cd my-app && typokit dev -
Enter your project and install dependencies
Terminal window cd my-apppnpm install -
Explore the project structure
Your scaffolded project looks like this:
my-app/├── src/│ ├── app.ts # App factory — registers routes and middleware│ ├── types.ts # Your schema type definitions│ ├── routes/ # Route modules (you'll add these next)│ ├── middleware/ # Global middleware│ └── services/ # Business logic layer├── package.json├── tsconfig.json└── .typokit/ # Auto-generated (validators, routes, schemas)See the Project Structure page for a full breakdown.
-
Define a type
Open
src/types.ts. This is where you define your domain types — the single source of truth for your entire stack:src/types.ts /** @table */export interface Todo {/** @id @generated uuid */id: string;/** @minLength 1 @maxLength 200 */title: string;completed: boolean;/** @generated now */createdAt: Date;}export type CreateTodoInput = Omit<Todo, "id" | "createdAt">;TypoKit reads these plain TypeScript types and generates validators, database schemas, and OpenAPI definitions automatically. No decorators, no Zod — just types.
Learn more in Schema-First Types.
-
Create a route
Define a route contract and handler for your
Todotype:src/routes/todos/contracts.ts import type { RouteContract } from "@typokit/types";import type { Todo, CreateTodoInput } from "../../types.ts";export interface TodoRoutes {"GET /todos": RouteContract<void, void, void, Todo[]>;"POST /todos": RouteContract<void, void, CreateTodoInput, Todo>;"GET /todos/:id": RouteContract<{ id: string }, void, void, Todo>;}src/routes/todos/handlers.ts import type { HandlerInput } from "@typokit/core";import type { TodoRoutes } from "./contracts.ts";import type { Todo } from "../../types.ts";const todos: Todo[] = [];type RouteHandlerFn<Route extends keyof TodoRoutes> = (input: HandlerInput<TodoRoutes[Route]>) => Promise<TodoRoutes[Route]["response"]>;const handlers: { [Route in keyof TodoRoutes]: RouteHandlerFn<Route> } = {"GET /todos": async () => {return todos;},"POST /todos": async ({ body }) => {const todo = {id: crypto.randomUUID(),title: body.title,completed: body.completed,createdAt: new Date(),};todos.push(todo);return todo;},"GET /todos/:id": async ({ params, ctx }) => {const todo = todos.find((t) => t.id === params.id);return todo ?? ctx.fail(404, "TODO_NOT_FOUND", `Todo ${params.id} not found`);},};export default handlers;Learn more in Routing and Handlers.
-
Register the route in your app
src/app.ts import { createApp } from "@typokit/core";import { nativeServer } from "@typokit/server-native";import todoHandlers from "./routes/todos/handlers.ts";export const app = createApp({server: nativeServer(),routes: [{prefix: "/todos",handlers: todoHandlers,},],});app.listen({ port: 3000 }).then(() => {console.log("🚀 Server running at http://localhost:3000");}); -
Start the dev server
Terminal window pnpm typokit devYou should see:
✔ Schema introspection complete (2 types found)✔ Validators generated✔ Routes compiled✔ OpenAPI spec generated🚀 Server running at http://localhost:3000👀 Watching for changes... -
Test your API
Open a new terminal and try it out:
Terminal window # Create a todocurl -X POST http://localhost:3000/todos \-H "Content-Type: application/json" \-d '{"title": "Learn TypoKit", "completed": false}'{"id": "a1b2c3d4-...","title": "Learn TypoKit","completed": false,"createdAt": "2026-03-02T12:00:00.000Z"}Terminal window # List all todoscurl http://localhost:3000/todos[{"id": "a1b2c3d4-...","title": "Learn TypoKit","completed": false,"createdAt": "2026-03-02T12:00:00.000Z"}]
What Just Happened?
Section titled “What Just Happened?”With just a few TypeScript types and a handful of files, TypoKit:
- Validated your request body against the
CreateTodoInputtype - Routed requests to the correct handler with full type safety
- Generated an OpenAPI spec at
/openapi.json - Watched your files for changes and rebuilt incrementally
Next Steps
Section titled “Next Steps”Now that you have a running app, dive deeper:
- Project Structure — Understand the layout of a TypoKit project
- Schema-First Types — Master the type system that powers everything
- Routing and Handlers — Learn about route contracts and handler patterns
- Middleware and Context — Add authentication, logging, and more
- Error Handling — Type-safe error responses with
ctx.fail() - Building Your First API — A complete, end-to-end tutorial