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 left on disk. --all prints one line per package. --strict exits 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. 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 |
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 (arguments land in shell history and ps). It runs through the kit’s own auth config with no bunx and 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. 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 |