# Build from source

> Prerequisites, then the commands that bring up the server and the desktop app from the repository.

Source: https://baalda.com/docs/build-from-source
Site: Baalda, https://baalda.com

You need this to work on Baalda or to run an unreleased build. To use the app, download a build instead, and to run a server, use one of the deployment options rather than a development checkout.

## Prerequisites

- Node.js 22 or newer. `corepack enable` activates the pinned pnpm.
- Rust and Cargo, from rustup.rs.
- Docker, which runs the Postgres database locally.
- On Linux only: Tauri's system dependencies plus `libdbus-1-dev`, the build header for the Secret Service keychain backend that stores the session token.

```bash
sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev \
  librsvg2-dev libxdo-dev libssl-dev libdbus-1-dev build-essential patchelf
```

## 1. Install dependencies

```bash
cd app
pnpm install
```

## 2. Start the server

Copy the example environment file and change `JWT_SECRET` before this is used for anything real. `db:up` starts Postgres in Docker on host port 5439.

```bash
cd apps/server
cp .env.example .env
pnpm run db:up
pnpm run migrate
pnpm run dev
```

That serves the HTTP API on port 3010, with the sync WebSocket at `/sync` on the same port. The legacy dedicated port 3011 also listens, but nothing in the repository needs it reachable.

## 3. Start the desktop app

```bash
pnpm run dev:desktop
```

Run that from the `app/` directory. It launches the Tauri app with Vite on port 1420.

## Project layout

```
app/
├── apps/desktop/   Tauri v2 app: Rust core (src-tauri/) + React/Vite/TS UI (src/)
└── apps/server/    Node/TS: Hono HTTP + Hocuspocus sync + Postgres + Better Auth + MCP
docs/               Product overview, build status, specs and reference research
```

## The stack, and why

| Layer | Choice | Why this one |
|---|---|---|
| Desktop shell | Tauri v2 (Rust core) | Real filesystem access behind a web UI, in a fraction of Electron's footprint |
| UI | React + Vite + TypeScript | A typed boundary to Rust, so the UI never touches the disk itself |
| Editor | CodeMirror 6 | The buffer is the Markdown, with no rich-text model to translate through |
| Files and watcher | Rust | Atomic writes plus a debounced watcher, so edits from an AI or `git` are noticed |
| Local index | SQLite with FTS5 | Entirely derived, so it is deletable and rebuilt from the files on demand |
| Real-time sync | Yjs and Hocuspocus | A person typing and an AI rewriting a paragraph merge as operations |
| Database | Postgres | Holds opaque binary updates, so Markdown never travels the wire |
| Accounts and teams | Better Auth with argon2id | Vaults map onto organizations, with per-folder permissions on top |

> For anything beyond a small fix, open an issue before you start. Some invariants in this architecture are load-bearing, and the repository's own architectural overview is the place to read them.
