An interactive dashboard for analyzing the BoardGameGeek database — exploring mechanic co-occurrences, trends, and underexplored design space niches.
Live demo: solojulian.dev/bgg
boardgames_ranks.csv file downloaded from BGG (CSV dump of all ranked games)Create a .env file (or export the variable) with your BGG API token:
BGG_API_TOKEN=your-token-here
Place the boardgames_ranks.csv in the project root, then run:
python3 ingest.py
This fetches game details from the BGG API in batches and builds bgg.db. It's resumable — if interrupted, re-run and it picks up where it left off.
./run.sh
This installs dependencies, builds the frontend, adds database indexes, and starts the Flask server on http://localhost:5000.
For frontend hot-reload during development:
# Terminal 1: Flask backend
python3 app.py
# Terminal 2: Vite dev server (proxies /api to Flask)
cd frontend && npm run dev
app.py Flask API server
ingest.py BGG API -> SQLite ingestion script
run.sh One-command setup and run
requirements.txt Python dependencies
frontend/
src/
App.svelte Tab navigation, header/footer
lib/api.js Fetch wrapper
views/
MechanicDashboard.svelte Heatmap + trend charts
MarketOpportunity.svelte Treemap + opportunity table
public/
bgg-logo.png "Powered by BGG" attribution logo
The database (bgg.db) is not included in this repo. BGG's XML API Terms of Use do not permit redistribution of their data. Use ingest.py with your own API token to build it.
| Table | Description |
|---|---|
games |
Core game data (30k rows) — ratings, weight, player count, play time, etc. |
mechanics |
192 unique mechanics |
categories |
85 unique categories |
families |
Game families |
designers |
Game designers |
game_mechanics |
Game-to-mechanic junction |
game_categories |
Game-to-category junction |
game_families |
Game-to-family junction |
game_designers |
Game-to-designer junction |
Data sourced from BoardGameGeek via their XML API. All game data belongs to BGG and its contributors.