Reactive mobile-first bus map built with Rust, Bevy, WGPU/WASM, and Axum.
- Show live bus positions from the Department for Transport Bus Open Data Service.
- Render geographically accurate route geometry for Dorset first, with support for more regions.
- Keep the domain model explicit and type driven so feed ingestion, APIs, and rendering stay aligned.
- Deploy as a static-capable web client plus a small Rust backend for proxying and normalization.
apps/web: Bevy + WASM client for mobile browsers.apps/api: Axum backend that proxies upstream realtime feeds and serves region manifests.crates/domain: Shared types for maps, routes, vehicles, filters, and API payloads.crates/region-pack: Region asset loading and manifest validation.crates/ingest: Upstream provider abstraction and BODS adapter skeleton.assets/regions/dorset: First external region package.docs: Architecture and project conventions.
- Copy
.env.exampleto.env. - Fill in
BODS_API_KEYfor live BODS data. You can get a key by creating a Bus Open Data Service account athttps://data.bus-data.dft.gov.uk/account/signup/and then copying the API key from your BODS account settings. Leave it unset to use the mock realtime provider. - Start the stack with
docker compose up --build.
The web app is exposed on http://localhost:8080.
In Docker development, the browser should use same-origin API requests at
http://localhost:8080/api/...; Trunk proxies those requests to the API service.
The API is also exposed directly on http://localhost:3000 for inspection.
The API container now runs cargo watch -x "run -p api" against a bind-mounted
workspace, so backend Rust edits are recompiled automatically without rebuilding
the image each time. You only need docker compose up --build when the Docker
image itself changes, such as after editing docker/Dockerfile.api.dev or
adding new system-level dependencies.
This scaffold now includes:
- typed Dorset region bootstrap from the backend
- static serving of external region assets
- a BODS SIRI-VM realtime adapter skeleton for vehicle positions
- a mock realtime provider fallback when no API key is configured
- Bevy web polling and rendering of routes, stops, and live vehicle markers
- client-side route filtering with backend query narrowing
- tap selection for vehicle details
- browser geolocation support for a follow-my-location viewport mode
Still to build: production-grade BODS normalization, proper touch gesture handling, search, stop detail views, and a richer mobile sheet/navigation model.
