A fast, minimal game discovery platform aggregating recent releases and upcoming titles across PC and consoles. Uses a custom PopScore algorithm to surface the most anticipated games.
- Curated Calendar: "Hyped" and "Other Upcoming" games, plus recent releases.
- PopScore: Custom 0-1 hype metric combining IGDB visits, wishlists, Steam players, reviews, and follows. Displayed as 0-100 in the UI.
- Smart Caching: In-memory cache with background cron updates (every 2h) for sub-millisecond API responses.
- Robust Backend: ElysiaJS with rate limiting, retries, and error handling for IGDB API interactions.
- Modern Frontend: Lit Web Components with Shadow DOM, plain CSS, and CSS Custom Properties.
- Type Safety: End-to-end via Elysia Eden Treaty.
- Runtime: Bun
- Backend: ElysiaJS
- Frontend: Lit
- Styling: Plain CSS (CSS Custom Properties)
- Data Source: IGDB API
├── src/
│ ├── components/ # Lit Web Components
│ │ ├── app.ts # Root component (app-main)
│ │ ├── card.ts # Game card (card-main)
│ │ ├── grid.ts # Responsive grid (grid-main)
│ │ ├── layout.ts # Layout wrapper (layout-main)
│ │ ├── footer.ts # Footer (footer-main)
│ │ ├── spinner.ts # Loading spinner (spinner-main)
│ │ └── error.ts # Error boundary (error-main)
│ ├── server/ # Backend logic
│ │ ├── index.ts # Elysia app, IGDB fetching, caching
│ │ ├── constants.ts # Config, weights, platform IDs
│ │ ├── types.ts # Shared TypeBox schemas
│ │ ├── utils.ts # Transformers and helpers
│ │ └── logger.ts # In-memory logger
│ ├── styles/
│ │ ├── theme.css # CSS Custom Properties
│ │ └── main.css # Global resets
│ └── main.ts # Frontend entry
├── data/ # Static IGDB mappings
├── build.ts # Bun bundler script
├── dev.ts # Dev orchestrator
└── index.html # App shell
bun installCreate a .env file:
TWITCH_CLIENT_ID="your_client_id"
TWITCH_CLIENT_SECRET="your_client_secret"Obtain credentials from the Twitch Developer Console.
bun devRuns the API and frontend watcher in parallel at http://localhost:3000.
bun run buildOutputs minified assets to dist/.
bun run check # Format & lint (auto-fix)
bun run check:ci # CI read-only check
bun run typecheck # TypeScript check- IGDB Proxy: Authenticates via Twitch OAuth, fetches release dates and game data with pagination.
- Caching: In-memory cache updated every 2 hours. Serves cached data instantly.
- Endpoints:
GET /& static assets — SPA shellGET /api/games— Cached game listGET /api/logs— In-memory logsGET /health— Health check
- Metrics are normalized against the 90th percentile of the dataset.
- Normalized values are clipped to [0, 1.25].
- Weighted sum is applied; weights differ for upcoming vs. released games.
- Final score is clamped to [0, 1].
Upcoming weights: wishlists, hypes, follows, want-to-play, visits, established series, Steam metrics. Released weights: Steam players, Steam reviews, top sellers, playing, visits, rating count, follows, want-to-play.
- SPA built with Lit Web Components.
- State: Reactive properties drive updates. Data fetched via
edenTreaty. - Styling: Each component uses Shadow DOM with plain CSS consuming theme variables.
- Responsive: 1-column mobile, 3-column tablet, 4-column desktop, 6-column wide.