All commands run from the repository root with Bun. turbo runs the graph-aware, cached tasks
across every workspace that defines the script.
| Command |
What |
bun run dev |
every app with a dev script: api :3000, web :5173, site :4321, docs :4322 |
bun run dev:app |
api + web only |
bun run dev:site · bun run dev:docs |
one Astro site |
bun run dev:desktop |
Tauri desktop shell around the dev server (needs Rust) |
| Command |
What |
bun run verify |
lint, check and test in CI’s order — the pre-push command; add bun run build for the whole pipeline |
bun run check |
turbo check — svelte-check in the app and packages, astro check in the sites |
bun run test |
turbo test — bun test in the TS packages and the API, Vitest (unit + component in Chromium) in the app, and packages/ui’s contrast check, which recomputes every token pair’s ratio from theme.css. The component tests need Playwright’s Chromium; apps/web’s pretest installs it on first run |
bun run test:e2e |
Playwright against a production preview of apps/web (includes axe, WCAG 2.2 AA) |
bun run lint · bun run lint:fix |
Biome — check / check and write (TS, JSON, CSS, Svelte, Astro; tabs, single quotes, 100 columns) |
bun run format |
Biome format only |
bun run build |
turbo build — every app |
bun run clean |
remove build outputs |
bun run licenses |
audit every dependency’s licence from the metadata an install already left on disk (--all for one line per package, --strict to exit 1 on anything not already recorded in THIRD-PARTY.md — what CI runs) |
bun run rename |
rename the kit to your product across the tracked text files: --name, --slug, --identifier, --scope. Dry run unless --write; LICENSE.md, THIRD-PARTY.md, CHANGELOG.md, UPGRADING.md and the script itself are left verbatim, and it prints a residue checklist of what a text substitution must not touch (Docker volumes, the dev database, .env, lockfiles, the kit’s own repository URL) |
| Command |
What |
bun run db:up · bun run db:down |
Postgres 17 + pgvector (pgvector/pgvector:pg17) in Docker via infra/compose.dev.yml (host port POSTGRES_PORT, default 5433) |
bun run db:migrate |
apply packages/db/drizzle/*.sql, then verify nothing is still pending and exit 1 if something is — a branch merge can interleave migration timestamps, which Drizzle’s migrator would otherwise skip while printing success |
bun run db:generate |
generate a migration from the schema |
bun run db:push |
push the schema without a migration (development only) |
bun run db:studio |
Drizzle Studio |
| Command |
What |
bun run auth:schema |
regenerate the Better Auth tables after changing plugins — then db:generate and db:migrate |
bun run admin:create -- --email … [--name …] [--yes] |
create or promote the first platform administrator. The password comes from ADMIN_PASSWORD or an interactive prompt, never from the command line, where it would land in shell history and ps. It runs through the kit’s own auth config — no bunx, no network — so it works inside the API container too. --yes is required to promote an account that already exists |
bun run seed |
demo data: demo@example.com / demo-password-1234 (SEED_PASSWORD overrides), one organization with a team, two workspaces, three documents, six finished jobs with their credit-ledger rows, and an audit trail. Idempotent, and it refuses to run with NODE_ENV=production. No object is written to storage, so a seeded document cannot be downloaded |
| Command |
What |
bun run api:openapi |
write apps/api/openapi.json for non-TypeScript client generation |
bun run --cwd apps/api worker |
run the job worker as its own process (then WORKER_ENABLED=false on the API) |
| Command |
What |
docker compose up -d --build |
production stack from the repository root (COMPOSE_FILE in .env) |
COMPOSE_PROFILES=backup in .env, then docker compose up -d |
nightly pg_dump (+ uploads); run --rm backup bun src/cli.ts backup|list|restore. Profiles live in .env, not on the command line — deploy.sh --remove-orphans drops containers of profiles it cannot see |
sudo REPO_URL=… EXPOSE=tailscale bash infra/scripts/provision.sh |
one-time VPS setup, as root (EXPOSE=public opens 80/443): Docker, Tailscale, deploy user, firewall, clone, .env — or curl … | sudo … bash as in the runbook |
bash infra/scripts/deploy.sh |
pull IMAGE_TAG, restart, wait healthy, hit /readyz (what CI runs over SSH) |
docker run --rm -i -e API_URL=… grafana/k6 run - < infra/loadtest/k6/smoke.js |
load test the API |
See Operations.
These are each app’s own scripts, not root ones: run them from that directory, or from the root with
bun run --cwd apps/<app> <script>.
| App |
Commands |
apps/web |
build (node) · build:node · build:cloudflare · build:static · build:static:desktop (into build-static/, what the Tauri shell bundles) · preview · check · test · test:e2e · i18n:compile · deploy:cloudflare |
apps/api |
dev · worker · bun test · openapi |
apps/site, apps/docs |
dev · build · preview · check · deploy:cloudflare (astro build && wrangler deploy) |
apps/native |
dev:desktop · build:desktop · `android:init |
packages/ui |
bunx shadcn-svelte@latest add <name> -c packages/ui |
infra/backup |
bun src/cli.ts backup|list|restore|schedule (image: infra/backup/Dockerfile) |
services/ai |
uv sync · uv run uvicorn ai.main:app --reload --port 8000 · uv run pytest · uv run ruff check . |
| Variable |
Effect |
ADAPTER=node|cloudflare|static |
selects the SvelteKit adapter for vite build in apps/web |
STATIC_OUT_DIR |
where ADAPTER=static writes (default build, the same directory the server adapters use). build:static:desktop sets it to build-static so a desktop build and a server build cannot overwrite each other |
SKIP_ENV_VALIDATION=1 |
relax the API’s env validation for steps that never boot the app (type checks, CI builds) — never for dev or migrate. Values are still parsed, so they keep their real types; only the cross-field production rules are skipped, and DATABASE_URL / BETTER_AUTH_SECRET get placeholders |
ADMIN_PASSWORD |
password for admin:create, instead of the interactive prompt |
SEED_PASSWORD |
password for the account bun run seed creates (default demo-password-1234) |
SITE_URL |
canonical origin for the Astro builds — each site has its own. astro build fails without it, and fails on an example.com placeholder; astro dev and astro check fall back to localhost:4321 / :4322 |