THE M4JORS Sweepstake • Personal
A golf pool that started as a spreadsheet and a group email. Six years later, it's a real-time web app with automated scoring, an admin panel and 67 entries at the last count.
What was going on
The M4jors is a golf sweepstake I've been running since 2020, timed around the four Major golf championships each year. The format came from my Dad, who'd been part of a similar competition with colleagues in America. He sent me it and I immediately wanted to run my own version.
The rules are specific, which is part of what makes it interesting: five players per team, one must come from the world's current top 5, the worst-performing pick is automatically dropped, but if two or more of your picks miss the cut your team is eliminated entirely.
Re: 2016 Masters Pool
Hi Guys,
It's that time of year again!
We're going to try a new format this year. Same $50 entry fee, winner take all.
Pick a team of 5 players — only one from the top 5 (McIlroy, Spieth, Day, Watson, Fowler). Winner is the team with the total lowest score. The catch: if any of your players miss the cut, you are out of the pool. Teams due by Thursday morning, 8am.
Invite friends if you can so we increase the size of the pool. Good luck to all!
Hoj
Howard B. Johnson · (203) 314-5123
The email that started it all
What needed solving
There wasn't one breaking point. There was a slow accumulation of friction: manual work that scaled badly, a frontend (spreadsheet) that looked terrible on mobile and processes that depended entirely on me being available to run them. The pool grew from 18 participants in 2020 to the mid-40s by 2022 entirely by word of mouth but the backend hadn't kept pace.
What I was working with
No budget and only my own personal time. Users ranging across age and technical comfort, most accessing everything on their phones. An event that runs four times a year, four days at a time, with a hard deadline I couldn't move. And real stakes — people paid money and would notice immediately if scoring was wrong. Participants weren't shy about telling me when something wasn't working either.
I was also learning as I built. Phase 1 was a spreadsheet because that's what I knew. Phase 5 is a React app with Firebase and a live ESPN API integration. Each version had to run a real competition while I worked out what came next.
How I worked through it
Phase 1 was pure necessity: get something working. I built formulas so player scores cascaded through to every entry that had picked them and sent nightly email updates summarising the standings that I had manually input myself.
Phase 2 moved team submission to a Google Form — better for me, no real difference for participants other than a nicer interaction than over email. Score entry was still manual each night.
Phase 3 came out of a constraint. The 2022 Masters coincided with a holiday in Morocco. I wasn't going to manually update scores from my phone between day trips, so I automated the backend before I left: IMPORTHTML pulling the ESPN leaderboard into the spreadsheet, a Google Apps Script running on a timer updating every five minutes. I came back from Morocco and the spreadsheet had run itself the whole time.
Phase 4 addressed the mobile problem. A large shared spreadsheet is objectively bad on a phone. I built a basic frontend reading from Google Sheets via API, deployed through Firebase. Finally, participants could check standings on their phones in a more responsive and reliable way. One manual pain point survived: the day 2 cut still required me to swap formulas for every player who'd missed it. Depending on the field, this could mean dozens of manual cell changes.
Phase 5 changed everything. I replaced the Google Form, the spreadsheet, the scraper and the basic frontend with a proper React app, a live ESPN API integration, a real admin panel and an invite-only access model — built and documented like a product, not a side project.
The Google Form entry — functional, but no validation or guardrails
The spreadsheet that ran four years of competitions — nightly manual updates until Morocco changed that
What shipped and why
The current version is a React app backed by Firebase: Firestore, Google Sign-In auth, Cloud Functions for the ESPN field sync, deployed as a Progressive Web App (PWA). Live scores pull from ESPN's public API every 60 seconds — no scraping, no intermediary server, no manual intervention.
The entry flow puts the rules first, deliberately. People pay real money. They should understand the format before they pick. The leaderboard handles cut detection automatically, state-changes eliminated teams, shows a live prize estimate per entry and expands to show your team as well as which of your five picks was dropped.
The access model was a deliberate call: invite-only, Google Sign-In for authentication, manual approval before anyone can enter. I get a push notification when someone new signs up. It keeps the pool private without me maintaining a password list or fielding reset requests from people who use the app once a year.
The entry flow — five steps, no spreadsheet
The admin overhead that used to take hours now takes minutes
What it changed
The pool has grown from 18 participants in the first-ever competition in 2020 to 67 entries at the 2026 Masters — entirely by word of mouth, no promotion. The trajectory maps almost exactly to the product improvements: growth was slow while the experience was a Google Form and a spreadsheet and accelerated once the app launched.
18
First competition (2020)
67
2026 Masters
+34%
Growth since app launch
My admin overhead during a live tournament went from a couple of hours a day to near zero. I set a tournament ID, click sync, open submissions and the app runs for four days without me. That matters — the manual version was starting to feel like an obligation. The automated one feels like something I'm proud of.
The leaderboard during the most recent live tournament — updated every 60 seconds, no intervention required
What I'd do differently
I'd have committed to the frontend rebuild sooner. The gap between having a solid automated backend (Phase 3) and shipping the proper app (Phase 5) was longer than it needed to be. I ran Phase 4 through multiple tournaments knowing it wasn't good enough, because building Phase 5 required time investment and upskilling that I kept deprioritising.
Next case study
Collective 2.0 • Whitespace