> ## Documentation Index
> Fetch the complete documentation index at: https://filament.getgalaxy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Local development

> Set up the toolchain and run Filament from source

## Toolchain

The Brewfile pins the toolchain (`go`, `just`, `golangci-lint`, `buf`, `sqlc`,
`node@22`, and `pnpm`). You also need Docker with Compose. Integration tests
use Testcontainers.

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
brew bundle
```

## Container engine

Docker is Filament's default container engine for local infrastructure, image
builds, and container-backed tests.

For Podman users, select your existing installation before running Filament's development commands:

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export CONTAINER_ENGINE=podman
just container-check
```

This selects Podman for `just infra`, `just images`, and container-backed tests.
Use the same selection for `just infra down`. Docker and Podman keep separate data.

Podman uses the `docker-compose` provider. On macOS, tests require a rootful
machine. Filament discovers its socket and configures privileged Ryuk automatically.
On Linux, the Podman API socket must be available. Keep Ryuk enabled for test cleanup.

## Workspace layout

The repository contains several Go modules joined by `go.work`, including the
root module, `cmd/`, selected connectors and secret providers, and `tests/`.
The justfile checks each module with `GOWORK=off`, so it is verified against its
own `go.mod` rather than dependencies supplied only by the workspace.

## The justfile is the dev CLI

Every routine task is a `just` recipe. These are the ones that matter day to
day.

| Recipe | What it does |
| - | - |
| `just infra` | Start PostgreSQL and NATS via Compose (`down` stops, `volumes` also drops data) |
| `just migrate` | Run datastore migrations against the local database |
| `just dev` | Worker + control plane + server in the background, wait for `:8082`, `:8080` and `:8081` `/startupz`, then the UI |
| `just worker` | Worker alone on `:8082`, answering connector calls and executing runs |
| `just server` | API server alone (runs `migrate` first), reaching the worker at `WORKER_URL` |
| `just control-plane` | Control plane alone, with `DISPATCH_MODE=worker` |
| `just ui` | Vite dev server on `:5173`, proxying the API to `:8080` |
| `just gen` | Regenerate protobuf/ConnectRPC stubs (`buf generate`) and sqlc code |
| `just ui-dist` | Build the UI bundle the server embeds |
| `just build` | `gen` + `ui-dist` + compile every Go module |
| `just binaries` | Linux release binaries into `bin/filament/` |
| `just images` | Build images with the selected container engine |
| `just docs` | Mintlify docs preview on `:3000` |
| `just tidy` | `go mod tidy` in every module, then `go work sync` |

Start `just infra` before `just dev`. The `dev` recipe runs migrations
immediately, so the database must already be healthy.

Formatting and linting take a mode argument, not a hyphenated name:

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
just format check   # verify formatting without writing
just lint check     # run linters without fixing
```

`just format` and `just lint` (no argument) fix in place. CI runs the
granular equivalents (`just go-lint check`, `just go-format check`,
`just ui-lint check`, and `just ui-format check`). See
[style and testing](/pages/guides/contributing/style-and-testing) for the
full lint and test story.

<Note>
  The justfile falls back to a hardcoded `ENCRYPTION_KEY` so `just server` works
  out of the box. It is a published dev credential — never reuse it outside
  local development.
</Note>

## Building the UI in

`just binaries` builds the server, standalone, and cli binaries with
`-tags embedui` so the compiled UI ships inside them. A plain `go build ./cmd/server` without
the tag serves a placeholder page at `/`, not the UI. `just ui-dist` produces
the embeddable bundle on its own.

## Building the worker images

The worker image is published in two builds. The plain tag is a static binary
on the static distroless base, like the server and control plane. The `-libc`
tag is the same program built with cgo on a glibc base, and it is the only
build that carries connectors linking native libraries. Each has its own
Dockerfile under `cmd/worker`, and anything such a connector needs at runtime
beyond the binary belongs in `Dockerfile.libc` alone.

`just binaries` cross-compiles the static binaries and builds the `-libc`
worker inside a Go container through the selected engine, because a cgo build
targets the host it runs on and cannot cross-compile from macOS. `just images`
tags it `worker:latest-libc`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.