Skip to content

Installation

  • Node.js >= 18 — required to run npm create kilat and wrangler (install). Bun is recommended for faster installs and is required for the test suite and build scripts (install Bun).
  • Cloudflare account — free tier is enough (sign up).
  • Wrangler — included as a devDependency, or install globally with npm i -g wrangler.
Terminal window
npm create kilat@latest my-app
cd my-app

Have Bun? bun create kilat@latest my-app is faster — Bun installs deps in seconds and runs the test suite and build scripts.

The interactive prompt picks a framework (React 19 / Svelte 5 / Vue 3) and styling (vanilla CSS / Tailwind CSS v4). It downloads the template, patches wrangler.toml, renames package.json, and installs dependencies.

Terminal window
npm create kilat my-app --template svelte-tailwind # skip prompts
npm create kilat . # use current dir
npm create kilat my-app --remote --template default # also create KV + R2

The --remote flag creates the KV namespace and R2 bucket on your Cloudflare account and patches wrangler.toml with the real IDs — skip the manual step of creating bindings yourself. If you’re not logged into Wrangler, it will skip remote creation and tell you to run npx wrangler login first. R2 will also fail gracefully if not yet enabled on your account (enable it at dash.cloudflare.com → R2).

Alternatively, clone directly:

Terminal window
git clone https://github.com/maulanashalihin/kilat.git my-app
cd my-app
bun install
# or: npm install (if you don't have Bun yet)

Open wrangler.toml and set your D1 database ID:

name = "my-app"
main = "src/worker.ts"
compatibility_date = "2025-07-01"
compatibility_flags = ["nodejs_compat"]
[vars]
NODE_ENV = "development"
SSR = "true"
MAIL_DRIVER = "log"
MAIL_FROM = "no-reply@example.com"
[[d1_databases]]
binding = "DB"
database_id = "your-database-id-here" # from `wrangler d1 create`
database_name = "kilat"
migrations_dir = "migrations"
[assets]
directory = "./dist"
binding = "ASSETS"
run_worker_first = ["/*", "!/assets/*"]

Sensitive values (API keys, OAuth secrets) should use wrangler secret put instead of [vars].

Terminal window
# 1. Create a D1 database (first time only)
npx wrangler d1 create kilat
# → copy the database_id into wrangler.toml
# 2. Apply migrations to local D1
bun run db:migrate
# 3. Build client assets (required before first dev run)
bun run build
# 4. Run the dev server
bun run dev # http://localhost:8787

Run bun run build again whenever client assets change — the Worker imports dist/manifest.json at module load.

Terminal window
# 1. Create the remote D1 database (first time only)
npx wrangler d1 create kilat
# → copy the database_id into wrangler.toml
# 2. Apply migrations to remote D1
npx wrangler d1 migrations apply kilat --remote
# 3. Build client assets
bun run build
# 4. Deploy to Workers edge
bun run deploy
# → https://<your-worker>.<your-subdomain>.workers.dev

That’s it. No Docker, no VPS, no reverse proxy. The Worker runs on Cloudflare’s edge network — 300+ locations worldwide. D1 replicates read-only copies to the nearest edge automatically.

Command What it does
bun run dev Wrangler dev server (local D1 + Workers runtime)
bun run build esbuild client assets → dist/ (+ manifest.json)
bun run deploy wrangler deploy to Cloudflare Workers edge
bun run db:migrate Apply D1 migrations locally
bun run db:migrate:remote Apply D1 migrations to remote (production)
bun run db:seed Create a demo user ([email] [password] [role] args)
bun run db:seed:remote Create a demo user on remote D1 (--remote flag)
bun run typecheck tsc --noEmit
bun run lint biome lint src tests scripts
bun run test E2E suite (bun test --isolate)