
Golf Tee Time Booking App for iOS & Android - fourth.
Golf in Colorado Springs is sold by the group, not the player. Three golfers with an empty seat either absorb the cost or spend the week asking around. fourth. posts the round, fills the seat, and tracks it hole by hole.
01The challenge
No reliable way to fill an open tee time
Open spots get re-posted across fragmented group chats, with no certainty who is committed until they show up at the first tee.
No shared feed
Open tee times never travel outside a golfer's existing group chats.
No arbiter for a claim
Two people claiming the same spot at once had nothing to settle it.
Rounds posted twice over
The same round in several threads means nobody knows who is actually confirmed.
No view from home
A golfer waiting on a round had no way to see where it had got to.
02What we built
Post a round, fill the seat, watch it play out
A golfer posts course, date, time and open places. The round lands in a live feed that others join in one tap, public or invite only.
Feed and atomic join
The public tee time feed with live spot counts, backed by a transaction two golfers cannot race.
Live round tracking
Hole by hole progress with pace and an estimated finish, shared through a link that needs no app.
Flutter build
Clean architecture on Riverpod and GoRouter, with Firebase Auth, Storage, Messaging and Cloud Functions.
Joining runs as a single atomic Firestore transaction that decrements the spot count and registers the golfer in one write, so the race condition behind double bookings cannot happen.
03In the app
One feed, every open seat
Course, time, host and handicap, with the spot count moving live.

Tee time feed
A golfer opens on rounds they can actually join today. Colour is reserved purely for status, so the feed reads at a glance before anything is tapped.
01Post in 20 seconds
Course, date, time, spot count and a public or private toggle.
02Live public feed
Open rounds with spot counts, host and handicap. Private rounds route through an invite only join.
03Atomic join
Decrements spots and registers the golfer in a single database write.
04Hole by hole tracking
Pace calculations and an estimated finish, shared through a web link.
05Colour as status
Fairway green for live, orange for low spots, red for cancelled or full. Nothing decorative.
04The instance
fourth., as it ships
The client mark. Screens follow.

Client mark
The wordmark is the one place the brand speaks in a voice other than the product's, a high contrast serif against an interface built from plain type.
Inside the app, colour is reserved for status: green for live, orange for low spots, red for full. The sage stays with the mark and nowhere else.
05Stack
One Flutter codebase on a Firebase backed stack
The tracker is a Next.js page so a spectator needs no app at all.
06Results
Verified build benchmarks
The numbers that mattered were about correctness, not volume.
Double bookings in production
Stream latency on the live feed
Dart files in a modular structure
Stores from one codebase
The architecture is exactly what we needed. Riverpod keeps everything reactive, the join transaction has never failed, and the deep link routing works perfectly from push notifications.
Founder, fourth. Golf App
Live on the App Store and Google Play
The claim race condition designed out, not patched
Spectators follow a round from a plain web link
Let us build your product's fourth.
Tell us the problem your users run into and we will bring the engineering to fix it, end to end.
Start a project

