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 installprovisions 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
Install dependencies
prepare script.Create your environment files
The committed Then, set
.env.example carries working local defaults and boots the whole stack API key-free.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).Start the infrastructure
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.Run the migrations
Seed initial data
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.Local services
Once everything is running, these are the local endpoints you can access:| Service | URL | Notes |
|---|---|---|
| Web UI | http://localhost:3000 | The Latitude app UI |
| API | http://localhost:3001 | Public API; health at /health |
| Ingest | http://localhost:3002 | OTLP trace ingest; health at /health |
| Workers | http://localhost:9090 | BullMQ workers; health at /health |
| Workflows | http://localhost:9091 | Temporal workers; health at /health |
| Mailpit | http://localhost:8025 | Local inbox — magic links land here |
| Temporal UI | http://localhost:8233 | See workflow executions |
| Drizzle Studio | https://local.drizzle.studio/?port=3003 | Postgres console — run pnpm --filter @platform/db-postgres pg:studio first |
Contributing workflow
The pre-commit hook runspnpm 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:
| Task | Command |
|---|---|
| Format | pnpm format |
| Lint | pnpm check |
| Typecheck | pnpm typecheck |
| Dead-code / unused deps | pnpm knip |
| Tests | pnpm test |
--filter, and pass flags after --:
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_*).
.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.