A real-time Formula 1 season dashboard and companion browser extension featuring live countdowns, race schedules, driver standings, qualifying results, and pre-session audio alarms.
The project utilizes a serverless, static-file architecture: a background Python scraping pipeline runs automatically via GitHub Actions, updates static JSON files under the api/ directory, and serves them directly to both the web dashboard (f1.trionine.com) and the F1 Dash browser extension.
- Automated Data Scraping: Scrapes standings, results, and qualifying times directly from the official F1 website.
- Race Order Alignment: Pulls master calendar data from F1Calendar.com to map and tag sessions with their correct round IDs.
- Static API Storage: Generates structured JSON files to prevent server overhead and load the dashboard instantly.
- Grid Tab: Renders qualifying grids (Q1, Q2, Q3) for completed and upcoming race weekends.
- Relative Time Toggle: Converts all session timings to dynamic relative countdowns.
Official Mozilla Add-on: Available on the Firefox Browser Add-ons Store.
- Live Toolbar Countdown: Digital monospace countdown clock tracking the exact time until the next practice, qualifying, sprint, or Grand Prix.
- Pre-Session Audio Alarms: Automatically plays the official F1 intro theme 5 minutes before green light (configurable from 5 to 30 mins).
- Session Selectors: Customize alerts for specific sessions (FP, SQ, Sprint, Quali, Race).
- Local Timezone Conversion: Converts all track session start times directly to your local timezone.
- Official Motorsport Typography: Styled with the official Formula 1 vector logo, Titillium Web, and JetBrains Mono.
- Cross-Browser Support: Manifest V3 compatible across Firefox, Chrome, Brave, and Edge.
f1/
├── .github/workflows/
│ └── run_api.yml # Runs scripts/update_api.py every 30 minutes
├── api/ # Autogenerated static JSON database
│ ├── current.json # Current season race calendar & sessions
│ ├── qualifying.json # Q1, Q2, and Q3 qualifying results
│ ├── results.json # Completed race podium finishes
│ └── standings.json # Driver championship standings
├── assets/ # Static icons and logos
├── css/
│ └── styles.css # Dark mode styling & responsive layout
├── extension/ # F1 Dash browser extension (Manifest V3)
│ ├── assets/ # Extension icons, audio theme & self-hosted webfonts
│ ├── background.js # Background alarms & audio playback engine
│ ├── manifest.json # Extension manifest (Firefox default)
│ ├── manifest.chrome.json # Chromium manifest (Service Worker + Offscreen)
│ ├── offscreen.html / .js # Offscreen audio host for Chromium service workers
│ ├── package.sh # Dual-build packaging script
│ ├── popup.html # Extension popup layout
│ ├── popup.css # Extension styling (Titillium Web & JetBrains Mono)
│ └── popup.js # Live countdown & session state engine
├── js/
│ └── app.js # Frontend UI rendering & countdown engine
├── scripts/
│ └── update_api.py # Scraping, normalization & generation script
├── index.html # Main dashboard HTML structure
└── CNAME # Custom domain configuration (f1.trionine.com)
The scraped API data is stored as static JSON files.
For local development:
- Event Calendar:
api/current.json - Race Results:
api/results.json - Championship Standings:
api/standings.json - Qualifying Results:
api/qualifying.json
For external projects or integrations, you can consume the live, CORS-enabled endpoints publicly:
- Event Calendar:
https://f1.trionine.com/api/current.json - Race Results:
https://f1.trionine.com/api/results.json - Championship Standings:
https://f1.trionine.com/api/standings.json - Qualifying Results:
https://f1.trionine.com/api/qualifying.json
Start a local HTTP server in the repository root:
python3 -m http.server 5000Navigate to http://localhost:5000 in your web browser.
To run the scraper manually, ensure your python virtual environment is active:
python scripts/update_api.pyRun the automated packaging script inside extension/:
cd extension
./package.shThis generates:
f1_alert.zip/f1_alert.xpi: Ready for Mozilla Add-on Developer Hub.f1_alert_chrome.zip/dist_chrome/: Ready for Chrome Web Store / Chromium.
- Open Firefox and go to
about:debugging#/runtime/this-firefox. - Click "Load Temporary Add-on..." and choose
extension/manifest.json.
- Run
./package.shinsideextension/. - Open
chrome://extensionsand enable Developer mode (top right). - Click "Load unpacked" and select the
extension/dist_chrome/directory.
This project is unofficial and is not associated in any way with Formula 1 companies. F1, FORMULA 1, and related marks are trademarks of Formula One Licensing B.V.