[ the problem — what was broken about finding a pickup game, who felt it, and why existing apps and group chats did not solve it ]
[ the problem, continued — what you decided the product had to prove, and the constraint that shaped the build ]
1 project · 3 packages · 2026
One product, built end to end. Below is the case study — what it is, how it’s built, and the decisions that mattered.
Find live pickup basketball. A map of courts showing who's playing right now. Court locations are crowd-sourced and seeded from OpenStreetMap; live activity comes from geo-verified check-ins and crowd reports.
[ the problem — what was broken about finding a pickup game, who felt it, and why existing apps and group chats did not solve it ]
[ the problem, continued — what you decided the product had to prove, and the constraint that shaped the build ]
A Go API on chi, typed queries via pgx + sqlc, goose migrations. PostGIS does the heavy lifting: radius search, court dedup on import, and geo-verification of check-ins against court polygons.
One Expo codebase for iOS, Android and web. MapLibre native on device, react-map-gl/maplibre on web, behind one map component. A Barlow-based design system with light and dark runs across every screen.
Courts seeded from OpenStreetMap, then corrected by the crowd. Tiles from OpenFreeMap — production maps with no API keys and no per-load billing.
sqlc over an ORM — Typed Go from real SQL. The queries stay readable, PostGIS functions are first-class instead of escape hatches, and the compiler catches a schema change before the tests do.
Geo-verified check-ins — A check-in only counts if the device is inside the court polygon. Trust the phone, not the user — it keeps the live count honest without any moderation queue.
MapLibre + OpenFreeMap — No map API keys, no per-load billing, no vendor that can reprice the core of the product overnight. Native and web renderers sit behind one component.
Seed, then crowd-source — Two thousand courts from OpenStreetMap on day one so the map is never empty, then let players correct and add. Cold start solved with data that already existed.