// the-unofficial — a case study
The UnOfficial
NBA media with data, fan tools, and a retention loop — not just hot takes. Read, play, explore: all in one platform.

// at_a_glance
Read / Play / Explore
Three pillars
One platform for fans
BallDontLie
Data source
Live games, stats, lineups
Next.js 14
Stack
App Router · Firebase
Solo
Built by one
Design · code · voice
Not a blog. A platform for hoops fans.
The UnOfficial is my NBA fan blog and publishing platform — built to capture the energy of "three friends, an opinion, and google machine spiral," without pretending to be insiders. The tone is intentionally optimistic, data-informed, and written like a group chat (but with better formatting).
// problem.1
Fan media stops at articles
Most NBA blogs give you opinions; you still bounce between five tabs for scores, trades, and stats. This one's a single surface.
// problem.2
The fun tools sit behind paywalls
Trade machines, advanced stats, player profiles — usually subscription-gated. Here, they're wired into the editorial flow, free.
// problem.3
AI shouldn't write the article
It should spot what's worth writing. Pipelines surface angles from real data; writers still bring the voice.
Seven surfaces, one codebase.
Three pillars — Read, Play, Explore. Each is a real feature set, not a button in a menu. All shipped from one solo repo.
AI research pipelines
BallDontLie game data feeds pitch generation — so the next article idea is never a blank page. Writers stay in the driver's seat.
Analytics engine
Writer-facing insights on what lands and what doesn't. Player profiles rolling out to readers next.
Hover stat-cards
Player mentions in articles surface live stats on hover — no click-away, no tab-hopping to check a number.
Trade Machine
Simulate real NBA trades with current rosters and contracts. The classic fan toy, built into the site.
Schedule & scores
Today and tomorrow's slate, front-and-center. Season context at a glance without leaving the page.
Playoffs hub
Stand-alone spaces for each series with running stat leaders. Live throughout the postseason.
Trivia → Bucks → Packs
A real engagement loop: play trivia to earn UnOfficial Bucks, spend on card packs, collect rosters. Fantasy leagues coming next.
Built on boring, reliable pieces.
The stack is small on purpose. Every piece earns its slot — no frameworks picked for novelty, no servers to babysit.
// stack.ts
// implementation_highlights
- 01
AI pipelines are editorial-assist, not auto-generation. The pipeline beats the blank page with real angles; writers bring the voice.
- 02
Every reader-facing surface (Trade Machine, stat cards, Playoffs hub) runs on the same stack as the writer tools. One codebase, one auth model, one deploy.
- 03
Publishing is first-class: draft → publish → unpublish lifecycle, Owner/Writer/Reader roles, single-use invite codes — all enforced by Firestore rules, not UI logic.
What the code taught me back.
“Publishing is a workflow, not a page.”
Drafts, previewing, unpublishing, and tagging are the difference between 'a site' and 'a platform.'
“Auth is easy; authorization is the product.”
The role model + Firestore rules are what make multi-writer publishing safe and scalable.
“Good UX is removing friction.”
Invites and role-based dashboards reduce admin overhead and keep writers focused on writing.
On the roadmap.
Shipping is a loop, not a line. Here's what's in the queue next.
- planned
Card Game v2 — fantasy-style lineups (5 starters · 1 sixth man · 2 bench), global leaderboard plus private leagues with custom packs.
- planned
Schedule & scores expansion — beyond today/tomorrow to full-week and month views with deeper drill-down.
- planned
Player profiles — finish rolling out reader-facing stat pages for the full league.
- planned
Scheduled publishing + editorial calendar for the writer side.
- planned
Newsletter/subscriptions + lightweight commenting for reader engagement.
- planned
"Read-to-me" audio versions of each article for on-the-go listening.
// shipped items listed in commit history
// end case study
Want the long version?
Happy to walk through the decisions, the trade-offs, and the parts that didn't work the first time.