Quickstart
Prerequisites
Section titled “Prerequisites”- Bun ≥ 1.4 — runtime, package manager and test runner for the whole repository.
- Docker — for the local Postgres.
- Python 3.13 +
uv— only forservices/ai. - Rust toolchain — only for
apps/native(the Tauri shells).
Install and run
Section titled “Install and run”Every command below is the same in bash and in PowerShell.
bun installcp .env.example .env # API, db tooling, composecp apps/web/.env.example apps/web/.envBETTER_AUTH_SECRET ships empty — a placeholder secret is the one thing that must not have a
default, and the API refuses to boot without it. Generate one and put it in .env:
bun -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Bun is used rather than openssl because it is the one generator every machine running this repo
already has; PowerShell has no openssl. Then:
bun run db:up # Postgres 17 + pgvector in Docker (127.0.0.1:5433 by default)bun run db:migrate # applies packages/db/drizzle/*.sql (exits 1 if any stay pending)
bun run dev:app # api on :3000 + web on :5173Then open http://localhost:5173. Apart from that one secret, the defaults in
.env.example are enough for the local loop: emails are printed to the API terminal, billing and
social sign-in stay off, and nothing is capped. See Configuration for what each variable switches on.
Other entry points
Section titled “Other entry points”| Command | What |
|---|---|
bun run dev |
every app with a dev script (api, web, site :4321, docs :4322) |
bun run dev:desktop |
Tauri desktop shell around the dev server (needs Rust) |
bun run verify |
lint, typecheck and tests, in CI’s order — before every push |
bun run check · bun run test · bun run lint · bun run build |
the same steps one at a time, plus the build. test runs Svelte components in a real browser, so it installs Playwright’s Chromium on first run |
bun run test:e2e |
Playwright against a production preview of apps/web |
bun run admin:create -- --email … [--name …] |
create the first platform administrator; the password comes from ADMIN_PASSWORD or a prompt |
bun run seed |
demo organization, workspaces, documents and jobs, so a fresh install does not open on six empty states |
cd services/ai && uv sync && uv run uvicorn ai.main:app --reload |
the Python service on :8000 |
The full list is in Commands.
First steps in the app
Section titled “First steps in the app”- Sign up at
/signupwith email and password. In development the verification email is printed to the API terminal;REQUIRE_EMAIL_VERIFICATIONdecides whether a session is issued before the address is verified (default: only in production). - Create an organization. It is the tenant and billing entity that owns members, invitations and teams. New sessions start in your first organization; the sidebar switcher changes it.
- Invite people from
/app/team— invitations are emailed as links that expire after 7 days — and give them the owner, admin or member role. - Create a workspace from
/app. Workspaces are the product container, scoped to the organization and optionally to a team.
First platform administrator
Section titled “First platform administrator”Platform administrators are users whose role is admin — independent of organization roles.
Create the first one from the command line, then promote others from /admin/users:
ADMIN_PASSWORD='…' bun run admin:create -- --email you@example.com --name 'You'# add --yes to promote an account that already existsWith ADMIN_PASSWORD unset the script prompts for one. The password is never read from the command
line, where it would stay in shell history and be visible in ps.
Demo data
Section titled “Demo data”A fresh database opens on empty states, which makes a broken feature hard to tell from an
unpopulated one. bun run seed creates a demo organization with a team, two workspaces, three
documents, six finished jobs with their credit-ledger rows and an audit trail, owned by
demo@example.com / demo-password-1234 (SEED_PASSWORD overrides). It is idempotent, it refuses
to run with NODE_ENV=production, and it writes no storage objects — so a seeded document can be
read and searched but not downloaded.
Where things live
Section titled “Where things live”apps/ web/ SvelteKit application — auth, orgs/teams, workspaces, billing, admin (thin client) api/ Hono on Bun — Better Auth, oRPC router (RPC + REST/OpenAPI), webhooks site/ Astro — marketing, pricing, blog, SEO docs/ Astro Starlight — this documentation native/ Tauri 2 — desktop + mobile shells around apps/web's static build (no IPC)packages/ api-contract/ oRPC + Zod contract: the API's single source of truth api-client/ typed client for the contract (browser, SSR, Tauri, Bun scripts) auth/ Better Auth server instance (API) and Svelte client factory (frontends) db/ Drizzle schema (generated auth tables + ours), migrations, Bun.SQL client billing/ plan catalog + Stripe client email/ provider abstraction (Resend / console) + templates env/ validated server environment (t3-env + Zod) storage/ document bytes: local disk with signed URLs, or S3/R2/MinIO ui/ shared Svelte 5 components (shadcn-svelte/bits-ui + thin form wrappers) + Tailwind tokens tsconfig/ shared TypeScript configsservices/ ai/ FastAPI service (uv) — internal, called by the API onlyinfra/ compose.yml self-hosted stack: postgres · api · web · ai · caddy compose.dev.yml Postgres for local development caddy/ subdomains.Caddyfile (public) · single-origin.Caddyfile (tailnet/LAN) docker/ Dockerfile.static (Astro sites → Caddy)Internal packages are consumed from source — no build step. Shared dependency versions are pinned
once in the root package.json catalog and referenced with catalog:.