Transit is an independent dashboard for bus and metro service in Montréal (STM) and Ottawa (OC Transpo), live at transit.yesid.dev. It shows what agencies publish and marks a value unknown when an agency does not publish it; it does not certify arrivals.

Reference Value
Subject and boundary First steps for a new contributor: run the dashboard, learn the three apps, find the next page.
Verified source README.md, CONTRIBUTING.md, AGENTS.md at main f32cd9b10a6cfa7ea87c07c979355c226e9ddbac, checked November 7, 2026.
Support state Supported contributor path. Only main and the live service are supported (SECURITY.md).

Run the dashboard in five minutes

Install Node from .nvmrc (22.x) and Bun from .bun-version (1.4.4 since #731, checked on main 81db4fde on November 10, 2026), then:

git clone https://github.com/yesid-dev/transit.git
cd transit
bun install --frozen-lockfile
bun run dev

Open http://localhost:5173. The Vite dev server proxies /data to the public snapshot origin https://data.yesid.dev, so you need internet access but no database, API key or Cloudflare account.

The three apps

App What it does Start reading
apps/db Captures feeds, normalizes them in PostgreSQL, computes rollups and publishes snapshots ‣
apps/data-proxy Serves published snapshots from R2 on the dashboard's own origin ‣
apps/web The public dashboard; reads snapshots and never touches the database ‣

Next steps by task

Task Page
Set up Python, a disposable database or generated assets ‣
Run the right checks before a pull request ‣
Interpret a percentage or a time window ‣
Learn a term ‣
Work with a coding agent AGENTS.md holds only local commands and constraints (portability, project boundaries, verification). Contributing needs no access to the private planning workspace.
Ask a question or report a problem ‣

License and attribution

Source code is under the MIT License. Agency data, map data, fonts and GSAP keep their own terms, listed in NOTICE. Transit is not affiliated with STM, OC Transpo or any other transit agency. The production site counts visits with cookieless Plausible; local runs and forks send nothing unless PUBLIC_PLAUSIBLE_DOMAIN is set.