← All projects

Padel Ranker

A private app for our 17-person padel group. Ratings are rebuilt from every match, and Americano and Mexicano nights get their own scoreboard that never touches the rankings.

Padel Ranker leaderboard with a live tournament banner, this week's movers and the player list
Leaderboard · mobile

The short version

players
17
league matches in the first cup
21
automated tests
76
hosting
£0

What it is

Padel Ranker is the private app for our 17-person padel group. Log a match and everyone's rating updates from the full history. Social Americano and Mexicano nights get their own scoreboard and medals without touching the serious numbers.

Then it grew a tournament mode. The first Chiltern Cup ran on it in August: seven pairs, 21 league matches, semi-finals and a final, live on everyone's phone.

What I had to steer

The rule I wouldn't bend: matches are the source of truth and ratings are derived, never typed in. Every result is an event and the ratings are rebuilt by replaying the whole log, so a rating can only change if a match result changes.

I also tuned the maths for a small, closely matched group: daily movement caps, lower weight for short matches, and peer nudges that change confidence but never rank.

What I wired together

React and TypeScript as a home-screen PWA with an offline retry page. Supabase for Postgres, auth and row-level security, plus an edge function for admin jobs. The openskill library wrapped in a pure, unit-tested replay engine. Name-and-PIN login on top of real Supabase accounts, the native share sheet for fixture images, and nightly backups through GitHub Actions.

Where I pushed it

Change one tuning constant and the whole history re-scores consistently. Peer nudges are anonymised, and the database records tournament match times rather than someone's watch. It all runs on free tiers.

The build log

A rating engine for the padel group

Our padel group is 17 people who play regularly, and that brings two problems. Matchmaking needs fair pairings, but any ranking someone keeps by hand drifts, and then people argue about it. And the social nights, Americano and Mexicano, are their own kind of fun and shouldn’t touch the serious rating.

The event log

The rating engine is event-sourced. Every match result and every admin correction is stored as an event, and current ratings come from replaying the whole log in order through the openskill engine. The same log always gives the same ratings. There’s no rating state sitting around waiting to drift, so an edit or a deletion just triggers a fresh replay, which takes milliseconds at 17 players. The engine is pure, with no I/O, and fully unit-tested.

Session nights

Session nights run on a separate data model with a pluggable pairing strategy. Sit-out rotation, scoring, medals and retention share one engine, and Americano and Mexicano are each just a function that generates the next round’s pairings. A ratings-balanced mode can drop into the same slot later. Session nights never write to the rankings.

It’s a React PWA on Vercel with Supabase behind it, including row-level security and an edge function for admin jobs like creating a member or resetting a PIN, all on the free tiers. The group uses it, and if a rating looks wrong, you fix the match and the rating follows.

The screenshots come from the app’s demo mode: our group’s real names with sample results, so the numbers aren’t anyone’s actual rating.

The Chiltern Cup ran on it

The group wanted a proper tournament, so the app grew one. Organisers set up an event with player-named pairs, a group or single-table format, and manual, random or rating-balanced fixtures. Scoring can differ by stage. Two courts run in order, standings update live and the top four go into a bracket.

The first was the Chiltern Cup on 15 August: seven pairs, everyone playing everyone across 21 league matches, then two semi-finals and a final. Every member saw a live banner on their home screen linking to fixtures, scores and the bracket.

Real events don’t run in order, so organisers can start any ready fixture when its court is free. The database records start and result times, and the live screen shows a running timer. Anyone can make a portrait fixture image and share it from their phone. The rankings stayed untouched throughout, because tournaments, like Americano nights, never write to the rating.

All 21 league results, both semis and the final are stored with their timings. The builder now defaults to reusable one-table settings for the next event, and the app got a lighter, greener look, a Pair Predictor and better home-screen behaviour.