# How to Set Up a Local Development Environment for Thunderbolt: A Complete Guide

> Set up a local development environment for Thunderbolt fast. Follow our guide to install Bun, Rust, Docker, and configure your .env files for a seamless setup.

- Repository: [Thunderbird/thunderbolt](https://github.com/thunderbird/thunderbolt)
- Tags: how-to-guide
- Published: 2026-04-19

---

**To set up a local development environment for Thunderbolt, install Bun, Rust, and Docker, then run `make setup`, configure your `.env` files, start the Docker infrastructure with `make docker-up`, and launch the backend (`bun dev` in `backend/`) and frontend (`bun dev` in root) in separate terminals.**

Thunderbolt is a cross-platform AI client built by the Thunderbird team that combines a **React + Vite** frontend, a **Bun‑powered Elysia** backend, and **Tauri** for desktop and mobile builds. This guide walks you through the exact commands and file configurations needed to build and run the entire stack on your local machine, based on the official repository structure in `thunderbird/thunderbolt`.

## Prerequisites for Thunderbolt Development

Before cloning the repository, ensure you have the three core toolchains installed:

1. **Bun** – The JavaScript runtime and package manager used for both frontend and backend scripts. Install from [bun.sh](https://bun.sh).
2. **Rust** – Required for compiling Tauri and native dependencies. Install via `rustup`.
3. **Docker** – Used to orchestrate PostgreSQL, PowerSync, and optional services. Docker Desktop or the Docker engine is sufficient.

## Step-by-Step Setup Guide

### Install Node-Level Dependencies

The repository provides a `make setup` target that runs `bun install` for both the frontend and the backend, and also pulls in any required Rust crates for Tauri.

```bash
git clone https://github.com/thunderbird/thunderbolt.git
cd thunderbolt
make setup

```

### Configure Environment Files

The repo ships example `.env` files that contain the necessary configuration variables for the backend and the client. Copy them to `.env` in the project root and in `backend/`:

```bash
cp .env.example .env
cp backend/.env.example backend/.env

```

### Start the Infrastructure Stack

Run `make docker-up` to spin up a PostgreSQL database and a PowerSync server via Docker Compose:

```bash
make docker-up

```

### Run the Backend

Start the API server with `bun dev` inside the `backend/` folder. This launches the **Elysia** application defined in [`backend/src/main.ts`](https://github.com/thunderbird/thunderbolt/blob/main/backend/src/main.ts).

```bash
cd backend
bun dev

```

### Run the Frontend

From the project root, execute `bun dev`; the Vite dev server will be reachable at `http://localhost:1420`. This mounts the React entry point in [`src/index.tsx`](https://github.com/thunderbird/thunderbolt/blob/main/src/index.tsx).

```bash
bun dev

```

### Run the Native App

Tauri can be launched for different platforms using the provided npm scripts:

* **Desktop:** `bun tauri:dev:desktop`
* **iOS Simulator:** `bun tauri:dev:ios`
* **Android Emulator:** `bun tauri:dev:android`

These steps are documented in the official development guide at [`docs/development.md`](https://github.com/thunderbird/thunderbolt/blob/main/docs/development.md) (lines 5‑34).

## Architecture Overview

Understanding the three-zone architecture helps you navigate the codebase when debugging or extending features:

| Zone | Components | Role |
|------|------------|------|
| **User Device** | UI (React 19 + Radix), State (Zustand + TanStack Query + Drizzle), AI client (Vercel AI SDK + MCP), optional **E2E encryption**, SQLite | Runs the entire UI, local data store, and optional client‑side encryption. |
| **Server Infrastructure** | **Backend API** (Elysia on Bun), **Auth** (Better Auth + OTP + OIDC), **Inference Proxy** (rate‑limiting & routing), **PowerSync** (sync engine), PostgreSQL | Provides authentication, model routing, and the sync back‑end that stores encrypted payloads. |
| **External Services** | LLM providers (Anthropic, OpenAI, Mistral, OpenRouter), OAuth providers (Google, Microsoft), PostHog (analytics), Resend (email) | Third‑party SaaS that the server talks to. |

Key architectural properties include:

* **Offline‑first** – SQLite is the source of truth; the app works without a network connection.
* **Cross‑platform** – a single React codebase compiles to desktop (macOS, Linux, Windows) and mobile (iOS, Android) via Tauri.
* **Model‑agnostic** – the inference proxy abstracts away LLM providers, allowing you to plug in any OpenAI‑compatible API key or a local model server (e.g., Ollama).
* **Self‑hostable** – the whole stack (backend, DB, PowerSync, auth) can be run locally with Docker Compose, making it ready for on‑prem deployments.

## Key Development Files

| File | Description | Link |
|------|-------------|------|
| [`docs/development.md`](https://github.com/thunderbird/thunderbolt/blob/main/docs/development.md) | Full quick‑start guide, required tools, `make` commands | [development.md](https://github.com/thunderbird/thunderbolt/blob/main/docs/development.md) |
| [`docs/architecture.md`](https://github.com/thunderbird/thunderbolt/blob/main/docs/architecture.md) | Mermaid diagram, zone breakdown, architectural properties | [architecture.md](https://github.com/thunderbird/thunderbolt/blob/main/docs/architecture.md) |
| [`backend/src/main.ts`](https://github.com/thunderbird/thunderbolt/blob/main/backend/src/main.ts) | Entry point for the Bun + Elysia API server | [main.ts](https://github.com/thunderbird/thunderbolt/blob/main/backend/src/main.ts) |
| [`src/index.tsx`](https://github.com/thunderbird/thunderbolt/blob/main/src/index.tsx) | React entry point, mounts the UI, sets up Zustand store | [index.tsx](https://github.com/thunderbird/thunderbolt/blob/main/src/index.tsx) |
| [`src/lib/http.ts`](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/http.ts) | Centralised HTTP client used by both frontend and backend | [http.ts](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/http.ts) |
| [`deploy/README.md`](https://github.com/thunderbird/thunderbolt/blob/main/deploy/README.md) | Docker‑Compose and Kubernetes deployment instructions | [deploy/README.md](https://github.com/thunderbird/thunderbolt/blob/main/deploy/README.md) |
| [`scripts/tauri.ts`](https://github.com/thunderbird/thunderbolt/blob/main/scripts/tauri.ts) | Tauri build scripts for desktop, iOS, Android | [tauri.ts](https://github.com/thunderbird/thunderbolt/blob/main/scripts/tauri.ts) |
| [`src/lib/crypto.ts`](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/crypto.ts) | Optional end‑to‑end encryption helpers | [crypto.ts](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/crypto.ts) |

These files together form the core of the local development workflow: the docs guide you through setup, the [`backend/src/main.ts`](https://github.com/thunderbird/thunderbolt/blob/main/backend/src/main.ts) and [`src/index.tsx`](https://github.com/thunderbird/thunderbolt/blob/main/src/index.tsx) launch the server and UI, and the auxiliary libraries ([`http.ts`](https://github.com/thunderbird/thunderbolt/blob/main/http.ts), [`crypto.ts`](https://github.com/thunderbird/thunderbolt/blob/main/crypto.ts)) illustrate how the frontend talks to the backend and optionally encrypts data.

## Common Configuration Examples

### One-Liner to Bootstrap the Repository

Clone, install dependencies, and prepare environment files in a single sequence:

```bash

# Clone, install, and start everything

git clone https://github.com/thunderbird/thunderbolt.git && cd thunderbolt
make setup && cp .env.example .env && cp backend/.env.example backend/.env
make docker-up        # PostgreSQL + PowerSync

# In separate terminals:

(cd backend && bun dev)   # backend API

bun dev                   # Vite dev server (http://localhost:1420)

```

### Running the Desktop Client

Launch the Tauri desktop wrapper after the frontend dev server is running:

```bash
bun tauri:dev:desktop   # opens the Tauri window on macOS / Linux / Windows

```

### Adding a Local LLM Provider (Ollama)

To integrate a local Ollama instance, create a model entry in [`frontend/src/lib/settings.ts`](https://github.com/thunderbird/thunderbolt/blob/main/frontend/src/lib/settings.ts):

```ts
export const MODEL_PROVIDERS = [
  {
    id: "ollama",
    name: "Ollama",
    endpoint: "http://localhost:11434/v1",
    apiKey: "",               // not required for local Ollama
  },
];

```

The UI will then list “Ollama” as a selectable model in the Settings screen.

### Enabling Optional End-to-End Encryption

Set the environment variable in `.env`:

```env
ENABLE_E2E_ENCRYPTION=true

```

When the app starts, the encryption layer ([`src/lib/crypto.ts`](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/crypto.ts)) will wrap all outgoing sync payloads with the client‑side key before sending them to PowerSync.

## Summary

- **Install three toolchains**: Bun (JavaScript runtime), Rust (for Tauri), and Docker (for PostgreSQL/PowerSync).
- **Use Make targets**: `make setup` installs dependencies, `make docker-up` starts infrastructure.
- **Configure environment**: Copy `.env.example` to `.env` in both root and `backend/` directories.
- **Start services**: Run backend with `bun dev` in `backend/`, frontend with `bun dev` in root (available at `http://localhost:1420`).
- **Build native apps**: Use `bun tauri:dev:desktop`, `bun tauri:dev:ios`, or `bun tauri:dev:android` for cross-platform testing.
- **Optional features**: Enable local LLM providers via [`frontend/src/lib/settings.ts`](https://github.com/thunderbird/thunderbolt/blob/main/frontend/src/lib/settings.ts) and toggle end-to-end encryption via `ENABLE_E2E_ENCRYPTION` in `.env`.

## Frequently Asked Questions

### What are the minimum hardware requirements for running Thunderbolt locally?

Thunderbolt runs efficiently on standard development hardware. You need approximately 4 GB of RAM to run the Docker stack (PostgreSQL and PowerSync) alongside the Bun backend and Vite frontend. For mobile development using the iOS Simulator or Android Emulator, macOS or a Linux distribution with KVM support is required, plus at least 10 GB of free disk space for Rust toolchains and Tauri build artifacts.

### Can I use a local LLM like Ollama instead of cloud providers?

Yes, Thunderbolt supports model-agnostic inference through its configuration layer. Add your local Ollama endpoint to the `MODEL_PROVIDERS` array in [`frontend/src/lib/settings.ts`](https://github.com/thunderbird/thunderbolt/blob/main/frontend/src/lib/settings.ts) with the endpoint `http://localhost:11434/v1` and an empty API key. The UI will automatically display Ollama as a selectable provider in the Settings screen, routing all chat completions through your local instance.

### How do I enable end-to-end encryption for local development?

Set the environment variable `ENABLE_E2E_ENCRYPTION=true` in your root `.env` file before starting the application. When enabled, the encryption layer defined in [`src/lib/crypto.ts`](https://github.com/thunderbird/thunderbolt/blob/main/src/lib/crypto.ts) automatically wraps all outgoing sync payloads with client-side keys before transmitting them to the PowerSync server. This ensures that even if the local PostgreSQL database is compromised, the data remains encrypted and unreadable without the client's decryption key.

### Is it possible to develop without Docker for the database layer?

While the official workflow recommends Docker for running PostgreSQL and PowerSync via `make docker-up`, you can manually install PostgreSQL 15+ and run the PowerSync service as a standalone binary if you prefer a container-free environment. However, you must ensure the database connection strings in `backend/.env` match your manual setup, and you will lose the convenience of the pre-configured Docker Compose network that handles service discovery between the sync engine and the backend API.