~/projectsDavis Brown

1 project · 3 packages · 2026

Projects

One product, built end to end. Below is the case study — what it is, how it’s built, and the decisions that mattered.

live · iOS · Android · web

Pull Up

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.

[ hero image — three app screens: map, court detail, check-in ]
role
Sole engineer — schema to gesture
server
Go · chi · pgx + sqlc · goose · PostGIS
app
Expo · React Native · MapLibre
data
OpenStreetMap seed · OpenFreeMap tiles · 0 API keys

The problem

[ 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 ]

How it’s built

server/ Go

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.

app/ TypeScript · Expo

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.

data/ OSM

Courts seeded from OpenStreetMap, then corrected by the crowd. Tiles from OpenFreeMap — production maps with no API keys and no per-load billing.

[ architecture diagram — app → API → PostGIS, tiles from OpenFreeMap ]

Decisions that mattered

  1. 01

    sqlc over an ORMTyped 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.

  2. 02

    Geo-verified check-insA 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.

  3. 03

    MapLibre + OpenFreeMapNo 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.

  4. 04

    Seed, then crowd-sourceTwo 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.

Try it