Skip to content
IVANVANROOYEN_DEV

Gamer's Grimoire

A dashboard for my indie game club: playtime, achievement progress and a shared backlog, pulled live from the Steam Web API.

ROLE
Solo project — design and build
TIMELINE
Jul — Aug 2026
STATUS
LIVE
TYPE
WEB APP · DASHBOARD
STACK
  • NEXT.JS
  • REACT
  • TYPESCRIPT
  • TAILWIND
  • STEAM API
  • IGDB
  • VERCEL
gamers-grimoire.vercel.app
Gamer's Grimoire home page: blackletter title over a green-tinted photo of the three club membersOpen the live site (gamers-grimoire.vercel.app)
BUILD TIME
1 WK
APIS — STEAM + IGDB
2
DATABASES
0
PAGES
3
01

The problem

Our club plays one game at a time, and who'd played what, how far everyone had got and what to play next all lived in a group chat. I wanted one page that answered those questions automatically, with nobody needing to log in or update anything.

02

The approach

  1. No database, no login

    The whole site runs off one config file — members, picks and nominations — plus live Steam data, so keeping it current is a one-line edit.

  2. Two APIs, one view

    Steam supplies playtime, achievements, ownership and Australian store pricing; IGDB adds time-to-beat estimates through Twitch OAuth with automatic token refresh, matched by title.

  3. Tiered caching

    Next.js revalidation at 10 minutes for player stats, 24 hours for store data and 7 days for IGDB keeps the dashboard current while staying inside API rate limits.

03

Architecture

All fetching happens on the server. Each source is cached for as long as its data can change, two server modules join and sort the results, and the three pages render from them. There is no database; the config file is the only thing edited by hand.

  • club.ts to club-stats.ts
  • Steam Web API to Player stats
  • Steam Web API to Store data
  • IGDB API to Time-to-beat
  • Player stats to club-stats.ts
  • Player stats to backlog.ts
  • Store data to backlog.ts
  • Time-to-beat to backlog.ts
  • club-stats.ts to / (dashboard)
  • club-stats.ts to /history
  • backlog.ts to /backlog
04

What it does

Dashboard: a terminal-style status panel listing the club and current pick, above the current game, Lorelei and the Laser Eyes

Dashboard

The current pick front and centre: each member's achievement progress, a race to finish, the rarest unlock in the club, and a terminal-style status panel that sums it all up.

Achievement gallery with unlocked and locked icons per member, and the BADlog of hours each member spent on other games in the last two weeks

Achievement gallery and the BADlog

Every achievement for every member, unlocked or still locked — plus the BADlog, which shows what everyone has been playing instead over the last two weeks.

Backlog page: nominated games with who nominated them, how many members own each and live Australian sale prices

Backlog

Games everyone already owns come first, then nominations with how many members own each one and live Australian sale prices — on-sale games sorted to the top.

The dashboard on a phone: blackletter title over a green-tinted photo of the three club members

Works on a phone

The same dashboard, fully responsive, so it gets checked from the couch as often as from a desk.

05

Tech stack

L1CLIENT
  • React 19UI
  • Tailwind CSS 4Styling
HTTPS · server-rendered HTML + RSC payload
L2SERVER
  • Next.js 16App Router, RSC
  • Fetch cacheRevalidation
  • TypeScriptLanguage
REST / JSON · server-side fetch, cached per source
L3DATA
  • Steam Web APIPrimary source
  • IGDB APITime-to-beat
  • club.tsConfig
L4PLATFORM
  • VercelHosting, CI
  • GitHubSource control
WHY THESE CHOICES
React 19
Component model fits the repeated member tables, tabs and galleries.
Tailwind CSS 4
Utility classes made the dark-fantasy theme quick to iterate on.
Next.js 16
Server components do all fetching, so API keys never reach the browser.
Fetch cache
Per-source cache lifetimes with no extra infrastructure to run.
TypeScript
Typed Steam and IGDB responses surface shape changes at build time.
Steam Web API
The source of truth for playtime, achievements, ownership and prices.
IGDB API
Licensed HowLongToBeat data, via Twitch OAuth with automatic token refresh.
club.ts
A typed file instead of a database: the data only changes once per pick.
Vercel
Free tier, and every push to the main branch deploys automatically.
GitHub
Version history, and pushes trigger the Vercel build.
06

The outcome

Deployed on Vercel and used by the club for each pick. It also became the design testbed for this portfolio — the tilt cards, CRT effects and command palette started here.