Quickstart
Prerequisites
Section titled “Prerequisites”- Bun 1.4 or newer: runtime, package manager and test runner for the whole repository.
- Docker: runs 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.
- Install dependencies and copy the env templates:
bun installcp .env.example .env # API, db tooling, composecp apps/web/.env.example apps/web/.env- Generate
BETTER_AUTH_SECRET. It ships empty, and the API refuses to boot without it. Put the output in.env:
bun -e "console.log(require('crypto').randomBytes(32).toString('hex'))"- Start Postgres, apply the migrations and run the app:
bun run db:up # Postgres 17 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. The defaults in .env.example are enough
for local development: emails print 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. Run it 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 and 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 |
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 prints 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. Give each person the owner, admin or member role. - Create a workspace from
/app. Workspaces hold the product data. Each one belongs to the organization and optionally to a team.
First platform administrator
Section titled “First platform administrator”Platform administrators are users whose role is admin. This role is 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, because arguments stay in shell history and are visible in ps.
Demo data
Section titled “Demo data”bun run seed fills a fresh database with a demo organization: a team, two workspaces, three
documents, six finished jobs with their credit-ledger rows and an audit trail. The owner is
demo@example.com / demo-password-1234 (SEED_PASSWORD overrides the password). The script is
idempotent and refuses to run with NODE_ENV=production. 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. There is no build step. Shared dependency versions are
pinned once in the root package.json catalog and referenced with catalog:.