Skip to content

CLI Reference

The Kora CLI provides commands for creating, developing, and managing Kora.js applications. It includes project scaffolding, a development server, schema migration tools, and type generation.

Installation

The CLI is included when you install kora or can be installed standalone:

bash
# Included with kora
pnpm add kora

# Or install standalone
pnpm add -D @korajs/cli

kora create

Scaffolds a new Kora.js application from a template.

Usage

bash
npx create-kora-app [name] [options]

Or if the CLI is installed:

bash
kora create [name] [options]

Arguments

ArgumentRequiredDescription
nameNoProject directory name. If omitted, you will be prompted.

Options

OptionTypeDefaultDescription
--templatestring--Template to use. Skips the template selection prompt.
--pmstring--Package manager (pnpm, npm, yarn, bun). Skips the package manager prompt.
--yes, -ybooleanfalseAccept all defaults (recommended template + auto-detected package manager).
--tailwind / --no-tailwindboolean--Use Tailwind CSS or plain CSS. Skips styling prompt.
--sync / --no-syncboolean--Include sync server or not. Skips sync prompt.
--skip-installbooleanfalseSkip installing dependencies.

Templates

TemplateStylingSyncDescription
react-tailwind-syncTailwind CSSYesRecommended. Polished dark-themed UI with real-time sync.
react-tailwindTailwind CSSNoTailwind CSS with local-only storage.
react-syncPlain CSSYesClean CSS with sync server.
react-basicPlain CSSNoMinimal setup with local-only storage.

All templates include DevTools enabled by default, SQLite WASM persistence, and a todo app with stats, filters, and a polished UI.

Interactive flow

When run without options, the CLI prompts for configuration:

$ npx create-kora-app my-app

  Kora.js - Offline-first application framework

  ? Select a template:
    > React + Tailwind (with sync)    (Recommended)
      React + Tailwind (local-only)
      React + CSS (with sync)
      React + CSS (local-only)

  ? Package manager:
    > pnpm
      npm
      yarn
      bun

  Creating my-app...
  Installing dependencies...

  Done! Next steps:
    cd my-app
    pnpm dev

Non-interactive usage

bash
# Use a specific template
npx create-kora-app my-app --template react-tailwind-sync --pm pnpm

# Accept all defaults (react-tailwind-sync + detected package manager)
npx create-kora-app my-app --yes

# Mix flags: Tailwind without sync
npx create-kora-app my-app --tailwind --no-sync --pm npm

Generated project structure

my-app/
  src/
    schema.ts           # Your schema definition
    main.tsx            # Application entry point
    App.tsx             # Example UI
    kora-worker.ts      # SQLite WASM worker entry
  server.ts             # (sync templates) sync server entry point
  kora/
    generated/
      types.ts          # Auto-generated TypeScript types
    migrations/         # Schema migration files
  package.json
  tsconfig.json
  vite.config.ts
  kora.config.ts        # Kora configuration

kora dev

Starts the full development environment with hot reloading, sync server, and DevTools.

Usage

bash
kora dev [options]

Options

OptionTypeDefaultDescription
--portnumber5173Vite dev server port.
--sync-portnumber3001Sync server port (if sync is configured).
--no-syncbooleanfalseDisable the sync server even if configured.
--no-watchbooleanfalseDisable schema file watching.

What it starts

  1. Vite dev server -- Serves your application with hot module replacement (HMR).
  2. Kora sync server -- Starts automatically if sync is configured in kora.config.ts. Not started for local-only apps.
  3. Schema watcher -- Watches your schema file for changes and automatically regenerates TypeScript types.

Example

bash
$ kora dev

  Kora.js Dev Server

  App:      http://localhost:5173
  Sync:     ws://localhost:3001

  Watching schema for changes...

Configuration file

The kora dev command reads from kora.config.ts in the project root:

typescript
// kora.config.ts
import { defineConfig } from 'korajs/config'

export default defineConfig({
  schema: './src/schema.ts',
  dev: {
    port: 5173,
    sync: {
      enabled: true,
      port: 3001,
      store: { type: 'sqlite', filename: './kora-dev.db' },
    },
    watch: {
      enabled: true,
      debounceMs: 300,
    },
  },
})

kora migrate

Detects schema changes, generates migration files, and applies migrations to the local store.

Usage

bash
kora migrate [options]

Options

OptionTypeDefaultDescription
--dry-runbooleanfalseShow what would change without generating or applying migrations.
--applybooleanfalseApply the migration immediately without prompting.
--schemastringAuto-detectedPath to schema file.
--dbstringFrom config/defaultSQLite path to use for --apply.
--output-dirstringkora/migrationsMigration output directory.
--forcebooleanfalseSkip breaking-change confirmation prompts.

Workflow

The migrate command compares the current schema version with the previous version and generates a migration file describing the changes.

$ kora migrate

  Detected schema change: v1 -> v2

  Changes:
    + todos.priority (enum: low, medium, high, default: medium)
    ~ todos.tags (string -> array<string>)
    - todos.legacyField (removed)

  Generated migration: kora/migrations/002-add-priority-change-tags.ts

  ? Apply migration to local store? (y/n)

Change types

SymbolMeaning
+New field added to a collection.
~Existing field type or configuration changed.
-Field removed from a collection.
++New collection added.
--Collection removed.

Generated migration file

typescript
// kora/migrations/002-add-priority-change-tags.ts
import { defineMigration } from 'korajs'

export default defineMigration({
  version: 2,
  description: 'Add priority field, change tags to array',

  up: {
    // Automatically generated SQL
    sql: [
      `ALTER TABLE todos ADD COLUMN priority TEXT DEFAULT 'medium' CHECK(priority IN ('low','medium','high'))`,
      `ALTER TABLE todos ADD COLUMN tags_new TEXT DEFAULT '[]'`,
      // Data migration handled below
    ],

    // Optional: transform existing data
    transform: async (tx) => {
      const rows = await tx.query('SELECT id, tags FROM todos')
      for (const row of rows) {
        const tagsArray = row.tags ? [row.tags] : []
        await tx.execute(
          'UPDATE todos SET tags_new = ? WHERE id = ?',
          [JSON.stringify(tagsArray), row.id]
        )
      }
    },
  },

  down: {
    sql: [
      `ALTER TABLE todos DROP COLUMN priority`,
    ],
  },
})

Dry run

bash
$ kora migrate --dry-run

  Detected schema change: v1 -> v2

  Changes:
    + todos.priority (enum: low, medium, high, default: medium)

  Would generate: kora/migrations/002-add-priority.ts
  No changes applied (dry run).

kora generate

Generates TypeScript types and other artifacts from your schema.

Usage

bash
kora generate <subcommand> [options]

Subcommands

kora generate types

Generates TypeScript type definitions from the current schema. These types provide full autocomplete and type checking for collection operations.

bash
kora generate types [options]
OptionTypeDefaultDescription
--outputstring'kora/generated/types.ts'Output file path.
--schemastring'./src/schema.ts'Path to the schema file.
bash
$ kora generate types

  Generated TypeScript types from schema v1
  Output: kora/generated/types.ts

Generated output

For a schema with a todos collection, the generated file contains:

typescript
// kora/generated/types.ts
// Auto-generated by Kora CLI. Do not edit manually.

export interface Todo {
  id: string
  title: string
  completed: boolean
  assignee: string | null
  tags: string[]
  notes: unknown          // Rich text (Yjs Y.Text)
  priority: 'low' | 'medium' | 'high'
  dueDate: number | null
  createdAt: number
}

export interface TodoInsert {
  title: string
  completed?: boolean
  assignee?: string | null
  tags?: string[]
  priority?: 'low' | 'medium' | 'high'
  dueDate?: number | null
  // createdAt is auto-set, not included
}

export interface TodoUpdate {
  title?: string
  completed?: boolean
  assignee?: string | null
  tags?: string[]
  priority?: 'low' | 'medium' | 'high'
  dueDate?: number | null
}

// Collection type map used internally by Kora
export interface KoraCollections {
  todos: {
    record: Todo
    insert: TodoInsert
    update: TodoUpdate
  }
}

TIP

When using kora dev, types are regenerated automatically whenever your schema file changes. You only need to run kora generate types manually when not using the dev server.


kora deploy

Deploys your Kora application to a cloud platform. Handles Dockerfile generation, server bundling, client building, and platform-specific configuration in a single command.

Looking for a step-by-step walkthrough?

See the Deployment guide for a beginner-friendly tutorial that covers everything from installing the Fly CLI to verifying sync works.

Usage

bash
kora deploy [options]
kora deploy status
kora deploy logs
kora deploy rollback [deployment-id]

Options

OptionTypeDefaultDescription
--platformstring(prompted)Target platform: fly, railway, aws-ecs, aws-lightsail. Coming soon: render, docker, kora-cloud
--appstring(directory name)Application name on the platform
--regionstringiadDeployment region (e.g., iad, lhr, syd, nrt)
--prodbooleanfalseDeploy to production environment
--confirmbooleanfalseNon-interactive mode — fails fast on missing data
--resetbooleanfalseDelete all deploy state and generated artifacts

Subcommands

kora deploy status

Shows the current deployment health, platform, app name, region, live URL, and sync URL.

kora deploy logs

Fetches recent logs from the deployed application.

kora deploy rollback [id]

Reverts the deployment to a previous version. If no id is provided, rolls back to the last known deployment.

Deployment Flow

When you run kora deploy, the following steps execute in order:

  1. Artifact generation — Creates Dockerfile, .dockerignore in .kora/deploy/
  2. CLI detection — Verifies the platform CLI is installed (e.g., flyctl)
  3. Authentication — Checks login state, prompts if needed
  4. Provisioning — Creates the app on the platform (idempotent — skips if exists)
  5. Server bundle — Bundles server.ts into a single server-bundled.js using esbuild
  6. Client build — Runs vite build to produce static assets in .kora/deploy/dist/
  7. Platform config — Generates fly.toml or railway.json
  8. Deploy — Pushes to the platform and returns live URLs

Deploy State

State is persisted in .kora/deploy/deploy.json. On subsequent deploys, stored values (platform, app name, region) are reused automatically.

Reset with:

bash
kora deploy --reset

Examples

bash
# Interactive first deploy
kora deploy

# Non-interactive (CI/CD)
kora deploy --platform=fly --app=my-kora-app --region=iad --confirm

# Deploy to AWS Lightsail
kora deploy --platform=aws-lightsail --app=my-app --region=us-east-1 --confirm

# Deploy to AWS ECS Fargate
kora deploy --platform=aws-ecs --app=my-app --region=us-east-1 --confirm

# Production deploy
kora deploy --prod --confirm

# Check status after deployment
kora deploy status

# View logs
kora deploy logs

# Rollback
kora deploy rollback

Prerequisites

PlatformRequirement
Fly.ioInstall flyctl, run fly auth login
RailwayInstall @railway/cli, run railway login
AWS ECSInstall Docker Desktop (must be running), AWS CLI, run aws configure
AWS LightsailInstall Docker Desktop (must be running), AWS CLI, lightsailctl plugin, run aws configure
RenderComing soon
Docker (self-hosted)Coming soon
Kora CloudComing soon

Project Requirements

Your project must have:

  • A package.json with any @korajs/* dependency
  • A server entry file: server.ts, server.js, src/server.ts, or src/server.js
  • vite installed as a dev dependency (for client builds)

TIP

The deploy command stores all generated artifacts in .kora/deploy/. Add this to your .gitignore:

.kora/deploy/

Global options

These options are available on all commands:

OptionDescription
--helpShow help for the command.
--versionShow the CLI version.
--cwd <path>Set the working directory. Defaults to the current directory.
--verboseEnable verbose logging output.
bash
kora --version
kora migrate --help
kora dev --cwd ./my-project