Skip to main content
Infrastructure (Postgres, ClickHouse, Redis, Mailpit, Temporal) runs in Docker, while the five Latitude services run directly on your host for fast hot reload. Core observability (trace ingest and viewing) works out of the box. AI-dependent features light up as you add the documented provider keys, see AI features.
This guide is for running Latitude locally for development. To self-host a production instance, see the Deployment guide instead.

Prerequisites

  • Node.js 25 and Python 3.13. If you use mise, mise install provisions both.
  • pnpm 10. Enable it with corepack enable.
  • Docker. Docker Desktop or any Docker Engine, used for the infrastructure containers.
  • goose — the ClickHouse migration tool. Install with brew install goose (or see goose releases on other platforms).
  • uv — the Python package manager for the evaluation optimizer runtime. Install with brew install uv (or see the uv docs).

Local setup

1

Install dependencies

pnpm install
This also configures the git pre-commit hooks via the prepare script.
cd packages/platform/op-gepa/python
uv venv && uv sync --all-extras --all-groups
Latitude includes a Python sidecar for the evaluation optimizer runtime.
2

Create your environment files

The committed .env.example carries working local defaults and boots the whole stack API key-free.
cp .env.example .env.development
cp .env.example .env.test
Then, set NODE_ENV=test in .env.test (.env.development already defaults to development). And point LAT_STORAGE_FS_ROOT (in both environments) at an absolute path for the local object store (the default is /tmp).
3

Build the workspace

pnpm build
Some platform packages must be compiled before the database migrations run.
4

Start the infrastructure

docker compose up -d
docker-compose.yml is for local infrastructure-only: Postgres (with pgvector extension), ClickHouse, two Redis instances (cache + BullMQ), Mailpit (local SMTP), and self-hosted Temporal instance and its UI.
5

Run the migrations

pnpm migrate
Runs the Postgres migrations (Drizzle Kit) and the ClickHouse migrations (goose).
6

Seed initial data

pnpm seed
Optionally create a sample organization, with a default project, a handful of users, an API key, and realistic sample telemetry across Postgres and ClickHouse — enough to sign in and exercise traces, search, issues, and evaluations immediately.
7

Start the services

Pick whichever you prefer — all run with hot reload:
# Infra + all services + Postgres studio, each in its own pane.
# Requires tmux and tmuxinator. Runs `docker compose up` for you,
# so you can skip the standalone infra step above.
pnpm tmux
8

Sign in locally

Open http://localhost:3000, regsiter or enter a seeded user (owner@acme.com or admin@acme.com), and click the magic link Mailpit captures at http://localhost:8025.
When dependencies, migrations, or generated artifacts drift, pnpm reset (clean → install → build → reset DBs) gives you a clean slate; pnpm catchup rebuilds and applies any new migrations without dropping data.

Local services

Once everything is running, these are the local endpoints you can access:
ServiceURLNotes
Web UIhttp://localhost:3000The Latitude app UI
APIhttp://localhost:3001Public API; health at /health
Ingesthttp://localhost:3002OTLP trace ingest; health at /health
Workershttp://localhost:9090BullMQ workers; health at /health
Workflowshttp://localhost:9091Temporal workers; health at /health
Mailpithttp://localhost:8025Local inbox — magic links land here
Temporal UIhttp://localhost:8233See workflow executions
Drizzle Studiohttps://local.drizzle.studio/?port=3003Postgres console — run pnpm --filter @platform/db-postgres pg:studio first

Contributing workflow

The pre-commit hook runs pnpm check, pnpm typecheck, and pnpm knip. It’s configured automatically on pnpm install; to (re)configure it in an existing clone run pnpm prepare. Before opening a pull requests, run the same checks CI runs:
TaskCommand
Formatpnpm format
Lintpnpm check
Typecheckpnpm typecheck
Dead-code / unused depspnpm knip
Testspnpm test
You can scope any task to a single package with --filter, and pass flags after --:
pnpm --filter @app/api test                          # one package
pnpm --filter @app/api test -- src/some-file.test.ts # one file
pnpm --filter @app/api test -- -t "health endpoint"  # by test name
Check out the full Contributing guidelines.

AI features

The local stack runs with no proprietary API keys, and the full test suite is guaranteed to pass with no keys set, that said:
  • Semantic trace/issue search and search highlights need Voyage AI (LAT_VOYAGE_API_KEY).
  • Flaggers, evaluations, conversation intelligence, issue summarization, and AI generation need Anthropic (LAT_ANTHROPIC_API_KEY) or Amazon Bedrock (LAT_AWS_*).
Add the relevant keys to .env.development to enable those features locally.

What’s next

Contributing

How to propose changes, our PR conventions, and the Code of Conduct.

Start tracing

Point an application at your local instance and watch traces arrive.