Skip to content
~/rajwat

May 2027

Résumé
Live Mini-League Dashboard4 min read

fpl-league

One page instead of ten, and scores net of hits

  • Go
  • REST APIs

What it is

A dashboard for the Fantasy Premier League mini-league I play in. On one page, live through a gameweek: everyone's score net of hits, their captain, the transfers they made, how many players they still have left to play, and what they left on the bench.

Who it helped

My league is competitive in the way that only a small league can be, which means the questions people ask on a Saturday are specific and the official app answers almost none of them. It is slow to update while matches are on, so the number on screen is behind the game you are watching. It gives you a total per manager and nothing else, no weekly winner, no monthly table, and never a word about the bench.

So the league did all of that by hand. The admin worked out everyone's bench points himself at the end of a week, which is a real chunk of someone's Sunday spent doing arithmetic that a computer should be doing. And the rest of us opened each other's teams one at a time, nine or ten taps deep in the app, to see who had captained whom, what transfers had gone through before the deadline, and how many players somebody still had left to play, which is the only number that tells you whether a lead is safe.

This is all of that on one page, updating live. You can see the whole league's captains at a glance, the transfers in and out, the players still to come and the bench, without leaving the tab or asking anyone.

The other fix is that the official weekly number is wrong for the purpose people use it for. FPL's gameweek figure is gross: it does not subtract the four points you paid for an extra transfer. So the column everyone screenshots on a Sunday is not the column the season total moves by, and someone who took two hits looks like they had a better week than they had. This subtracts the hit, so the weekly figure and the league table finally agree. On top of that it keeps the two tallies nobody was keeping properly, the weekly win, decided net of hits, and the most points left on the bench, plus monthly standings built from FPL's own calendar months. Ties are shared rather than broken arbitrarily, because if two managers post the same score there is no honest way to pick one.

The bench rule is the part I am most pleased with, and it looks wrong until you know it. A Bench Boost week cannot win the bench tally, because the bench played: nothing was left behind. So one manager's 22 bench points count and another's do not, in the same gameweek, and that is the correct answer rather than a bug.

What went well

The CLI and the web page are the same program. `-serve` puts the existing report behind an HTTP API and serves one embedded HTML file against it, so the gross-versus-net rule and the Bench Boost rule exist once. Two implementations of a scoring rule is two chances to disagree, and the disagreement always surfaces as an argument in the group chat rather than as an error.

I also refused to encode anything by colour alone. The palette here holds its accents at near-constant lightness and separates them by hue, which is right for reading code and wrong for reading a chart, run through a colour-vision check, blue and purple land 0.4 ΔE apart for a deuteranope. So the bench meter is one hue varying in length, chips carry their two-letter label, and rank movement carries an arrow with the colour only as a second channel.

It was also the best practice I have had at living inside somebody else's API. FPL's endpoints are not designed for this, the data you need is spread across a call per manager per gameweek, so the page talks to two endpoints of my own instead, and the server does the fan-out. A manager's squad is fetched once, lazily, only when you open them, and cached against that manager and gameweek, so the Team, Captain and To-play tabs all read one payload and flipping between them costs nothing.

What's next

The season view still reports zero bench points for a Bench Boost week, while the gameweek view recomputes the real figure. That is a deliberate trade, recomputing it costs two extra calls per manager per boosted week, but it means the same fact reads differently on two tabs of the same page, and a reader has no way to know which one to believe.

The default league id is also written in three places that have to be changed together, which is exactly the kind of thing that is fine until the day it isn't.