A complete, automatically-synced dataset of every category on Twitch — including category ID, name, box art URL, and IGDB ID.
Inspired from Nerothos/TwithGameList and extended with automated daily syncing via GitHub Actions.
The dataset lives in data/index.json and is automatically updated every day at 00:00 UTC by fetching from the Twitch Helix API.
{
"meta": {
"last_synced": "2026-04-05T00:00:00.000Z",
"total": 58000,
"source": "https://api.twitch.tv/helix/games/top"
},
"categories": [
{
"id": "509658",
"name": "Just Chatting",
"box_art_url": "https://static-cdn.jtvnw.net/ttv-boxart/509658-{width}x{height}.jpg",
"igdb_id": null
}
]
}
| Field | Type | Description |
|---|---|---|
id |
string |
Twitch category ID |
name |
string |
Category display name |
box_art_url |
string |
Box art URL template — replace {width} and {height} with pixel dimensions |
igdb_id |
string \| null |
IGDB ID, if available |
Box art URLs use {width}x{height} placeholders rather than hardcoded dimensions. Replace them at runtime with whatever size you need:
const url = category.box_art_url
.replace('{width}', 285)
.replace('{height}', 380);
Common sizes used by Twitch: 52x72, 188x250, 285x380, 600x800.
For any new integration, prefer data/index.json as it is the actively maintained source of truth.
A GitHub Actions workflow runs daily and keeps data/index.json current.
GET /helix/games/top (100 games/categories per page) until the cursor is exhausted.You can trigger a sync at any time from the Actions tab. There is also a Full Resync option that ignores existing data and re-fetches everything from scratch — useful if the dataset gets corrupted or you want to force a clean rebuild.
Set these in your repo under Settings → Secrets and variables → Actions:
| Secret | Description |
|---|---|
TWITCH_CLIENT_ID |
Your Twitch application client ID |
TWITCH_CLIENT_SECRET |
Your Twitch application client secret |
Register a Twitch application at dev.twitch.tv/console to obtain these credentials. The app doesn’t need any special scopes — the games endpoint is public and only requires an app access token.
git clone https://github.com/seanquijote/twitch-category-index.git
cd twitch-category-index
npm install
TWITCH_CLIENT_ID=your_client_id \
TWITCH_CLIENT_SECRET=your_client_secret \
node scripts/sync.js
To force a full resync from scratch:
TWITCH_CLIENT_ID=your_client_id \
TWITCH_CLIENT_SECRET=your_client_secret \
FULL_RESYNC=true \
node scripts/sync.js
The script writes output to data/index.json.
.
├── .github/
│ └── workflows/
│ └── sync-twitch-categories.yml # Daily sync workflow
├── data/
│ └── index.json # Auto-updated dataset (primary)
├── lib/
│ └── api.js — fetchAllCategories (pagination)
│ └── auth.js — getAccessToken (Twitch OAuth)
│ └── config.js — All constants and resolved file-system paths
│ └── http.js — httpsGet, httpsPost, sleep (no business logic)
│ └── store.js — readData, buildOutput, writeData (all fs usage)
│ └── transform.js — normaliseCategory, mergeCategories (pure, zero I/O)
│ └── types.js — JSDoc @typedefs only (Category, RawCategory, CategoriesOutput, etc.)
├── scripts/
│ └── sync.js # Sync script
├── tests/
│ └── sync.test.js # Sync script unit test
├── .env.example # Sample .env file
├── .gitignore
├── LICENSE
├── package.json
├── package-lock.json
└── README.md
Pull requests are welcome. For bugs or suggestions, please open an issue.
If you notice the data is stale or a sync has failed, check the Actions tab for workflow run logs.
Original dataset and concept by Nerothos.