A real-time London bus tracking application that visualizes bus routes, headways, and live vehicle positions using data from Transport for London (TfL) and bustimes.org.
- Live Bus Tracking: View real-time positions of buses on your selected routes
- Headway Visualization: See the spacing between buses on a route to identify bunching or gaps
- Arrival Predictions: Get live arrival predictions for all stops on a route
- Multi-Route Support: Track multiple bus routes simultaneously
- Auto-Refresh: Automatically update bus positions at configurable intervals
- Supplementary Data: Enhanced vehicle tracking via bustimes.org integration
- Persistent Settings: Your routes and preferences are automatically saved and restored on page reload
- Theme Selection: Choose between light, dark, or system-default color themes
- React 19 with React Compiler
- Vite for fast development and building
- ESLint for code quality
- Express.js 5 for the API server
- Node.js runtime
- TfL Unified API - Primary source for route data, stop sequences, and arrival predictions
- bustimes.org - Supplementary source for real-time vehicle GPS positions
Some need to be set in your .env:
TFL_APP_ID=
TFL_APP_Key=- Node.js 18+ recommended
- npm or yarn
-
Clone the repository:
git clone <repository-url> cd headwaylondon
-
Install dependencies:
npm install
-
Create a
.envfile in the root directory (optional):PORT=3001
Start both the frontend dev server and backend API server:
npm run devI do not recommend running it as a one-liner, I use concurrently to do this. Instead, I recommend using two different terminals for the frontend and backend.
This runs:
- Vite dev server (frontend) on
http://localhost:5173 - Express server (backend API) on
http://localhost:3001
You can also run them separately:
# Frontend only
npm run dev:web
# Backend only
npm run dev:servernpm run buildnpm run previewnpm run lintheadwaylondon/
├── src/ # Frontend React source
│ ├── components/ # React components
│ │ ├── Header.jsx
│ │ ├── RouteControls.jsx
│ │ ├── RoutesInputPanel.jsx
│ │ ├── OptionsPanel.jsx
│ │ ├── HelpPanel.jsx
│ │ └── RouteDiagram.jsx
│ ├── utils/ # Utility functions
│ ├── api.js # API client functions
│ ├── App.jsx # Main application component
│ ├── App.css # Application styles
│ ├── index.css # Global styles
│ └── main.jsx # Entry point
├── server/ # Backend Express server
│ ├── index.js # Main server file with API routes
│ ├── tflClient.js # TfL API client with caching
│ └── bustimesClient.js # bustimes.org API client
├── public/ # Static assets
├── package.json # Project dependencies and scripts
├── vite.config.js # Vite configuration
└── eslint.config.js # ESLint configuration
The backend server proxies requests to external APIs:
| Endpoint | Description |
|---|---|
GET /api/line/:lineId/info |
Route metadata (origin/destination, stops, disruptions) |
GET /api/line/:lineId/sequence |
Ordered stop sequence and route geometry |
GET /api/line/:lineId/arrivals |
Live vehicle predictions |
GET /api/stop/:stopId/arrivals |
Arrivals for a specific stop |
| Endpoint | Description |
|---|---|
GET /api/bustimes/services?search= |
Search for bus service by route number |
GET /api/bustimes/vehicles?service= |
Live GPS positions for a service |
| Endpoint | Description |
|---|---|
GET /api/health |
Server health check |
The application includes an options panel where you can configure:
- Target Headway (minutes): Desired spacing between buses
- Average Stop Time (seconds): Time spent at each stop for calculations
- Auto-Refresh: Enable/disable automatic updates
- Refresh Interval (seconds): How often to poll for updates
- Theme: Choose between light, dark, or system-default color themes
Your tracked routes and all option settings are automatically saved to your browser's local storage. When you return to the application, your previous session will be restored automatically. To clear saved routes, use the "Clear All" button in the Routes panel.
| Variable | Default | Description |
|---|---|---|
PORT |
3001 |
Port for the Express backend server |
This project is provided as-is for educational and informational purposes.
- Transport for London for providing open bus data
- bustimes.org for supplementary vehicle tracking data
- Vite for the excellent build tooling
- React for the UI library
Contributions are welcome! Please feel free to submit issues and pull requests.