vStats: a stats and fair-play platform for VALORANT players
A live platform with player profiles, a statistical fair-play indicator, pages in five languages and Stripe subscriptions. One backend serves the website, a mobile app, two desktop apps and a partner integration.
- Role
- Designed and built (backend, web front end, billing, infrastructure)
- Type
- Own product
- Status
- Live
- Platform
- Web, plus mobile and desktop clients on the same API
The problem
Players want to look up anyone's rank, match history and form, and to judge whether a lobby looks fair. Before choosing an architecture I measured the official match history: it only reaches about 90 recent entries per player. A third-party data service goes deeper, but its rate limits are shared. Competitive teams also wanted one place for practice and strategy. And the whole platform had to run cheaply, survive outages at its data providers, and be found by search engines.
What I built
I designed and built a modular Node/Express backend of about 25,600 lines. It serves the website, a mobile app, two desktop apps and a partner sign-in integration from one API. Player data comes from two sources: the official Riot Games API, with a production key and Riot Sign-On so players can prove they own an account, and a third-party data service for deeper history, which runs under its own request budget. Redis holds sessions, caches and SEO summaries, and team data lives in PostgreSQL with plain-SQL migrations. Stripe Checkout and the Billing Portal handle subscriptions, with webhooks deciding who has access. Profile and stats pages are rendered on the server in five languages. A separate status page, hosted on Cloudflare, watches the whole system.
Highlights
PAYMENTS
Subscriptions where the webhook decides access.
Premium and Teams plans run through Stripe Checkout and the Billing Portal, so card details never touch my server. Webhooks handle access, refunds and cancellations, and deleting an account cancels its subscriptions. The server can also verify Apple App Store subscriptions, as a second payment path.
OAUTH
Sign-in in both directions.
vStats is a client of Riot Sign-On, and it is also an OAuth 2.0 provider for partner sites: vStats Connect lets a site without its own Riot API key link players' verified accounts. It is built on Node's built-in crypto, with no extra dependencies.
SCORING
ARBITER, a statistical fair-play indicator.
A Bayesian model combines several categories of statistical evidence into one score. It gives context; it is not cheat detection. I moved it from three client-side copies into one server-side service, so web, mobile and desktop all show the same number.
SEO & I18N
Search engines never wait on an upstream API.
Profile pages render from summaries cached in Redis, so a crawl never triggers an upstream call. Sitemaps, IndexNow submission, crawl-budget metering for bots, and stats pages in English, Brazilian Portuguese, Spanish, Turkish and Japanese with hreflang.
RESILIENCE
Built to stay up.
Size-bounded caches resist floods of unique keys, a budget keeps calls within the data service's limits, and process-level error handlers catch the unexpected. Alerts (Discord, with email fallback) fire on memory pressure, unclean restarts and bursts of server errors. The public status page, with 90-day history, is hosted separately from the main server.
CRAFT
A design system and hand-written PNGs.
CSS tokens plus 28 React/TypeScript components, each with its own documentation page. Heatmaps are rendered on the server as PNG files with no image library: the file chunks and compression are written by hand.
How it works
- Five kinds of client (website, mobile app, vStats Desktop, vStats Teams, partner site) call one Node/Express API.
- The API reads and writes Redis (sessions, caches, SEO summaries) and PostgreSQL (team data).
- It fetches player data from the Riot Games API and a third-party data service.
- Stripe and the App Store verification path report subscription changes back to the API.
- A status page on Cloudflare checks the API and its dependencies from outside.
Stack
- Node.js
- Express
- PostgreSQL
- Redis
- Stripe
- App Store Server API
- Riot Games API
- Riot Sign-On
- Cloudflare Workers & Turnstile
- HTML/CSS/JavaScript
- React + TypeScript (design system)
- Expo / React Native
- Tauri
By the numbers
- ~25,600lines of server code
- ~200HTTP routes
- 53test files (~14,400 lines), run against an in-memory Postgres
- 5site languages
- 6regions in server-rendered profiles
- 28documented components
Outcome
vStats is live at vstats.xyz in five languages, with Stripe subscriptions and a public status page at status.vstats.xyz. The same backend supports a mobile app, two desktop apps and a partner integration without a second API.
Need something like this? Get a free quote.
Get a free quoteVALORANT and Riot Games are trademarks of Riot Games, Inc. This project is not affiliated with or endorsed by Riot Games.