All work
Case study01 / 04 · September 2026

NPFL Fantasy

A fantasy football game for Nigeria's top flight, built around one hard fact: the league has no player-statistics feed.

Read the product brief Private repository
Role
Product, data design and build
Type
Mobile app, API and admin console
Built
5 to 13 Sep 2026 · 45 commits
Stack
Expo, Node.js, PostgreSQL
Status
In development
20

Clubs in the 2026/27 season

38

Matchdays to score

700+

Automated tests across engine, API and app

15

Players per squad, on a ₦100m budget

The opportunity

Why it exists

Nigeria has one of the most engaged Fantasy Premier League communities in the world and no official game for its own league. A partnership announced around 2018 never shipped. The audience already knows squads, captains and wildcards and spends all of it on English football. For 2026/27 a new sponsorship lifted the title prize to ₦1 billion, so the league has more attention than it has had in years.

What I built

What's in it

A monorepo in three parts. A rules engine for scoring, bonus points, chips, auto-substitutions, formations and gameweeks. A Node and PostgreSQL API with accounts, squads, transfers, leagues, pricing and an admin console that imports players from CSV and Excel. And an Expo app, Android first, covering onboarding with an 18+ age gate, the squad picker, a 3D stadium view of your team, points, fixtures, leagues and rewards.

Highlights

How it handles missing data

Every fantasy game you have played sits on a paid data contract. This one could not, and that shaped every decision.

  1. 01

    The data pipeline is the product

    Goalscorers for an NPFL fixture are usually published, minutes are approximate and assists are often missing. So most of the work went into the pipeline that collects, checks and corrects match data. The app is the easier half.

  2. 02

    Say what you don't know

    A missing assist is stored as unknown, never as zero, and the app tells the manager why a score is incomplete. When a fixture lacks the data to rank players fairly, no bonus is awarded rather than a guessed one.

  3. 03

    Scores can be re-run

    Points are calculated from stored inputs every time rather than added up in place. When a correction arrives after publication, the gameweek is re-scored and the change is shown line by line.

  4. 04

    Four tiers of evidence

    Official teamsheets, live stewards, club social media and video review each have a defined say over what they may overwrite. Social media can raise a task for a person to check. It can never change a stat by itself.

  5. 05

    Built for patchy connections

    Requests give up after eight seconds and the app falls back to cached data. Each kind of data is cached for as long as it stays true: clubs for a week, live scores for two minutes.

Hosted here

Try it right here

Open in a new tab

The app itself needs its API and database to run, so the page hosted here is the product brief.

Build notes

Decisions worth keeping

Private repository. NPFL Fantasy is still in development and its code is not public. The app needs its API and database to run, so the page hosted here is the product brief written alongside it.

Access rules in the database

PostgreSQL row-level security backs up the API, with tests that try to read other managers' data and expect to fail.

A security review before launch

An OWASP Top 10 review of the engine, API and app, written up in the repository on 7 September.

No borrowed crests

Each of the twenty clubs gets a mark from one shared system, so the app belongs to the league and not to any one club.

  • React Native
  • Expo
  • Three.js
  • Node.js
  • Express
  • PostgreSQL
  • Jest