← All work/Case 01

ProReview

In-depth match analysis for Counter-Strike 2

A web app that turns a CS2 match file into a clear breakdown of what went wrong and what to practise next. The file never leaves the player’s computer.

Type
Self-initiated product
My role
Design, front end, back end
Interface
English and Russian, light and dark
Live site
Launching soon
22-second product walkthrough2D viewer, progress, plans
#01

The task

Players who want to improve have hours of match recordings and no quick way to see where rounds were lost.

I wanted a tool that reads a match file and answers three questions: where did I die, why, and what should I practise next. Files had to stay private, so the analysis needed to run on the player’s own device.

#02

What I did

I designed and built the whole product: the interface, the analysis engine, the server, accounts and billing.

The analysis is a static site that works on its own. The accounts server sits on top of it and adds sign-in, plans, payments, Discord and an admin panel.

#03

Key features

  • Analysis in the browser.dem, .dem.gz and .dem.zst files are processed on the device in 20–60 seconds. Nothing is uploaded.
  • Deep breakdownDeaths, kills, duels, shooting and time-to-kill, rounds, positions, and what each type of mistake costs in Elo.
  • 2D round replayRadars for 44 maps, with upper and lower levels on Nuke and Vertigo, a timeline, drawing, zoom and hotkeys. A 3D view is built in three.js.
  • Mistake playlistEvery death with the same mistake, back to back.
  • Progress over timeCharts across the last 10 or 50 matches: rating, ADR, headshot rate, first-bullet accuracy and opening deaths.
  • Post-match homeworkThe three most expensive deaths and a drill for the main mistake, with a daily streak.
  • My matchesMatches stored privately in the browser and reopened instantly.
  • Accounts and plansEmail sign-up, Steam and FACEIT sign-in, Free, Pro, Team and Tier 1 plans with Paddle billing, Discord and an admin panel.
#04

Stack

Front end
  • JavaScript (ES modules)
  • Web Workers
  • IndexedDB
  • three.js
  • esbuild
Back end
  • Node.js 22
  • node:sqlite
  • node:test
  • No framework
Integrations
  • Steam OpenID
  • FACEIT OAuth 2.0 + PKCE
  • Paddle
  • Discord API
Tooling
  • Custom i18n build (Node + Python)
#05

Challenges

  1. Large files, no uploads

    ProblemA full match file is big, and players shouldn’t have to send it to a server.

    SolutionParsing runs in a Web Worker, so the interface stays responsive while the match is read. Compressed files are unpacked on the device.

  2. Maps with more than one level

    ProblemOn Nuke and Vertigo, areas sit on top of each other, so a single radar puts players in the wrong place.

    SolutionSeparate upper and lower radars, with each player shown on the level they’re actually on.

  3. Accounts people can trust

    ProblemReal sign-ups and payments mean real security requirements.

    SolutionPasswords are stored only as salted scrypt hashes. Session cookies are HttpOnly, and only a hash of each token is kept. One-time email links are hashed and expire. Cross-site requests are rejected, sign-in and sign-up are rate limited, and “forgot password” answers the same way for any address, so it can’t be used to find out who is registered.

  4. Three ways in, one account

    ProblemPlayers use email, Steam or FACEIT, and often more than one.

    SolutionAll three link to a single profile. Steam responses are verified with Steam itself, and Steam and FACEIT sign-in is bound to the browser that started it.

#06

Result

A complete, working product: analysis, accounts, plans and billing in one place.

Authentication, admin, billing and the Discord integration are covered by automated tests.

#07

Screens

Map radar images © Valve Corporation. ProReview is an independent project and is not affiliated with Valve.

Need a web app like this?

Logins, payments, dashboards and data. Tell me what you’re building and I’ll reply within one working day.

Send a message