How to set up each app on your own machine, including the Python pipeline, a disposable database and generated assets.
| Reference | Value |
|---|---|
| Subject and boundary | Local environments for apps/web, apps/data-proxy and apps/db. Checks to run are on ‣. |
| Verified source | CONTRIBUTING.md, AGENTS.md, package.json, pyproject.toml, target_safety.py at main f32cd9b10a6cfa7ea87c07c979355c226e9ddbac, checked November 7, 2026. |
| Support state | Supported on Linux and Windows for the JavaScript apps and the offline Python suite. Tests that drive Bash scripts and POSIX processes are only covered on Linux, as in CI. |
| Tool | Pin owner | Current source value |
|---|---|---|
| Node | .nvmrc, engines.node |
22.23.2 (>=22.17.0 <23) |
| Bun | .bun-version, packageManager |
1.4.4 (since #731; main 81db4fde, read 2026-11-10) |
| Python | .python-version, requires-python |
3.12 (>=3.12,<3.13) |
| Python packages | apps/db/uv.lock via uv |
Locked |
| JavaScript packages | bun.lock |
Frozen in CI |
Read versions from these files rather than copying them elsewhere.
bun install --frozen-lockfile
bun run setup:hooks # pre-commit guard for generated social cards and icons
bun run dev # web dashboard on http://localhost:5173
bun run test:changed # fast local loop: Vitest --changed vs origin/main + impacted Playwright specs (#727)
For dependency changes, run bun install on the selected native host and commit the intended lockfile change. CI's pinned Linux bun install --frozen-lockfile decides whether it works; regenerate on Linux only if that install fails. For unchanged source, a local frozen-install failure is a setup problem and incidental lockfile changes stay out of the commit.
The web scripts regenerate TypeScript contract types from src/lib/v1/schemas/json (scripts/gen-contract.mjs) before dev, check, test and build.
| Asset | Build | Check |
|---|---|---|
Social cards (static/og) |
bun run og:build |
bun run og:check |
| Icons | bun run icons:build |
bun run icons:check |
| Map posters | bun run map-posters:build |
bun run map-posters:check |
Run these from apps/web. The pre-commit hook rejects a staged generated card or icon unless its generator or input is staged too.
cd apps/db
cp ../../.env.example .env
uv sync --locked
uv run transit-ops --help
Use uv-managed Python on Windows; the system Python on this host has an incomplete standard library. Do not run Docker locally on any host; service images are built on the production VM (Deployment and release). Bash and POSIX operator examples below target Linux; use native PowerShell environment assignment for Windows offline tests.
The tracked .env.example defaults to local storage (BRONZE_STORAGE_BACKEND=local, SNAPSHOT_STORAGE_BACKEND=local), so nothing is written to a remote bucket by accident. Capturing live feeds needs provider keys: STM_API_KEY and OCTRANSPO_API_KEY, plus the feed URL variables named in each provider manifest. See Providers for each feed's variables and Configuration reference for the full list.
Real-database tests skip unless both variables are set. The target guard accepts only the role/database pairs transit_ci/transit_ci, postgres/transit_test and repro/transit_repro.
export TRANSIT_TEST_DATABASE_URL=postgresql+psycopg://transit_ci:[email protected]:5432/transit_ci
export TRANSIT_TEST_DATABASE_DISPOSABLE=I_UNDERSTAND_THIS_DATABASE_IS_DISPOSABLE
DATABASE_URL="$TRANSIT_TEST_DATABASE_URL" uv run alembic upgrade head
uv run pytest tests
Use a local PostgreSQL 16 with PostGIS. These tests change the database contents. Never point tests or migrations at production; a remote migration also refuses a URL loaded implicitly from .env (migration_guard.py).