Quick Start
This walks through running Thunderbolt locally: backend API, PowerSync sync service, and the Vite frontend.
Prerequisites
After cloning, run make doctor — it inspects your machine and prints exact install commands for anything missing. The most common needs are:
- Bun 1.2+
- Rust toolchain — for Tauri desktop and mobile builds (install via rustup)
- sccache — optional;
make setupinstalls it when Cargo is available to speed up Rust rebuilds - Docker — PowerSync and PostgreSQL run in containers during local dev
You’ll also need at least one AI provider API key — Anthropic, OpenAI, Mistral, Fireworks, or any OpenAI-compatible endpoint (Ollama and llama.cpp are recommended for local inference).
Linux desktop builds
Tauri needs GTK/WebKit dev libraries. On Debian/Ubuntu:
sudo apt install libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev \ build-essential curl wget file pkg-config libxdo-dev libssl-dev \ libayatana-appindicator3-dev librsvg2-dev libsoup-3.0-devFor other distributions, use the upstream
Tauri Linux prerequisites. make doctor checks for these on Linux.
Bootstrap
-
Clone and install.
Terminal window git clone https://github.com/thunderbird/thunderbolt.gitcd thunderboltmake setupmake setupinstalls frontend and backend dependencies, optionally installssccache, and wires up the Claude Code agent symlinks. -
Create
.envfiles.Terminal window cp .env.example .envcp backend/.env.example backend/.envmake doctormake doctorgenerates aBETTER_AUTH_SECRETforbackend/.envautomatically if it’s empty or still set to the placeholder. Add at least one AI provider key (e.g.ANTHROPIC_API_KEY) — see Configuration for the full list. Root.envis for the Vite/Tauri frontend;backend/.envis for the API server. -
Start Postgres + PowerSync.
Terminal window make upThis runs
docker compose -f powersync-service/docker-compose.yml up -d. PowerSync listens on:8080, Postgres on:5433(the non-default port avoids clashing with a local Postgres). Verify withmake status. -
Run the dev servers.
Browser (recommended):
Terminal window make runBackend starts on
http://localhost:8000, frontend onhttp://localhost:1420.Desktop (Tauri):
make dev-desktopiOS simulator:
make dev-ios(boot a simulator first:open -a Simulator)Android emulator:
make dev-androidUse the
make dev-*targets rather than thebun tauri:dev:*scripts underneath them. Each one starts the backend and then works around a failure mode: Tauri brings its own Vite, somake runalongsidebun tauri:dev:desktopcollides on:1420;tauri ios devmatches simulators by name and otherwise auto-selects a Wi-Fi-paired iPhone; andgen/androidis committed for the production identifier, so an Android dev build must re-init it for the.devone or it crashes withClassNotFoundException. Mobile Setup has the details. -
Sign in. Open
http://localhost:1420, create an account, and send a message. If it works, you’re good.
Common Issues
make upport conflict — something is bound to5433or8080. Stop it or editpowersync-service/docker-compose.yml.make upfails with a Postgres data-format error — the Postgres image was bumped to v18, which changed its on-disk layout. If your local volume was created with an older version, runmake nuketo wipe it and re-init (you’ll lose any local DB state).- Backend errors with
BETTER_AUTH_SECRET— runmake doctor; it generates one for you. Or set it manually withopenssl rand -base64 32. powersyncJwtSecret must be at least 32 characters— setPOWERSYNC_JWT_SECRETinbackend/.envto match the one baked intopowersync-service/config/config.yaml.- Playwright on Ubuntu 26.04 ARM64 —
make setupautomatically uses Playwright’s Ubuntu 24.04 ARM64 browser build until Playwright supports 26.04 directly. - Tests behave weirdly — fake timers are globally installed; see testing.md.
Helpful Makefile Targets
| Command | What it does |
|---|---|
make doctor |
Verifies your tools + env files. make doctor-q only prints issues. |
make run / make dev |
Starts backend + frontend. Kills stale processes on :8000 and :1420 first. |
make up |
Starts PowerSync and Postgres. |
make down |
Stops containers, keeps volumes. |
make nuke |
Wipes all container data and rebuilds from scratch. |
make check |
Runs type-check, lint, format-check, and the license-header check. |
make test |
Frontend test suite, then backend. |
make format |
Formats frontend, backend, and Rust. |
make help lists the full set.
The license-header step is the part of make check a first contribution most often trips on: every source file needs the three-line MPL-2.0 header. bun run license:fix adds it to anything missing one, and scripts/license-headers.ts knows the comment syntax for .ts, .tsx, .js, .jsx, .cjs, .mjs, .css, .scss, .rs, .kt, .kts, .sh, .sql, .html, and .astro. The pre-commit hook already runs it over staged files, so you normally only see the failure when committing outside the hook.
Next Steps
- Configuration Reference — every backend env var.
- Mobile Setup — iOS / Android / desktop Tauri dev prerequisites.
- Architecture — how the pieces connect.
- Testing — how to run each suite, the globally installed fake timers, the
mock.module()hazard, and the Playwright e2e setup. - Composite Primary Keys and Default Data and Multi-Device Sync — schema rules for synced tables.
- Self-Hosting — deploy Thunderbolt somewhere real.