Free, open source golf tracking and improvement platform.
OGA does what paid apps like Arccos, Shot Scope, and Break X Golf do — shot tracking, strokes gained analysis, shot pattern dispersion, lie-aware filtering — and charges nothing. The core belief: getting better at golf shouldn't be paywalled.
- Web: https://oga.golf — live
- Android & iOS: in pre-launch (dual-store). The app is built and running on device; store listings are in final prep.
- Round logging — hole-by-hole shot entry with club, lie type, and split lie-slope axes (forward/back tilt + ball above/below feet).
- Live round mode — GPS-assisted shot tracking with a Mapbox satellite view, Kalman-smoothed ball position, and a 3-tap flow.
- Strokes gained — off tee, approach, around green, putting; baselines interpolated by handicap bracket from Mark Broadie's Every Shot Counts.
- Shot patterns — per-club dispersion ellipses (68% / 95%), miss tendency, aim-correction tips, lie-aware filtering, shareable cards.
- Practice plans — drills tuned to your weakest SG categories, generated by an AI coach (a Supabase Edge Function) from a curated ~125-drill library tagged by practice mode.
- Course database — ~15,300 US golf courses with GPS coordinates and
per-tee rating/slope; fuzzy search backed by
pg_trgm. - Handicap index — calculated from your recent rounds against the played tee's course rating + slope.
- Learn section — a golf glossary and 20+ progress-focused articles.
- Putting model — independent short/long and left/right miss axes, green speed, slope %, and break direction captured per putt.
- Monorepo: Turborepo + pnpm workspaces.
- Web: Vite + React 18 + TypeScript + Tailwind.
- Mobile: Expo SDK 53 + Expo Router + React Native 0.79 + React 19.
NativeWind pinned at
4.1.23. Builds run on EAS. - Backend: Supabase (Postgres + Auth + Row Level Security + Edge Functions).
- Maps: Mapbox GL JS (web) +
@rnmapbox/maps(mobile). - Packages:
@oga/core— pure TypeScript: math, stats, SG calculation, Kalman GPS smoother, shot-pattern fitting, all shared domain types.@oga/supabase— generated Supabase types + client factory + query helpers.
The short version is below. For the full walk-through (forking, Vercel deploy, EAS setup, troubleshooting), see docs/self-hosting.md.
- Node.js 20+
- pnpm 10+
- Supabase account (free tier is plenty)
- Mapbox account (free tier covers 50,000 map loads/month — required for mobile, optional for web)
# 1. Clone
git clone https://github.com/cner-smith/opengolfapp.git
cd opengolfapp
# 2. Install dependencies
# Mobile is decoupled from the workspace and uses npm with
# --legacy-peer-deps; do not lift it into pnpm.
pnpm install
cd apps/mobile && npm install --legacy-peer-deps && cd ../..
# 3. Create a Supabase project at https://supabase.com
# Copy the project URL, anon key, and service-role key.
# 4. Apply database migrations
npx supabase link --project-ref <your-project-ref>
npx supabase db pushSet up environment variables.
apps/web/.env.local:
VITE_SUPABASE_URL=<your-supabase-url>
VITE_SUPABASE_ANON_KEY=<your-anon-key>
VITE_MAPBOX_TOKEN=<your-mapbox-public-token>
apps/mobile/.env:
EXPO_PUBLIC_SUPABASE_URL=<your-supabase-url>
EXPO_PUBLIC_SUPABASE_ANON_KEY=<your-anon-key>
EXPO_PUBLIC_MAPBOX_TOKEN=<your-mapbox-public-token>
For mobile device testing, EXPO_PUBLIC_SUPABASE_URL must be your
machine's LAN IP (e.g. http://192.168.1.108:54321) when pointing at
local Supabase, not localhost.
The courses / holes / course_tees tables ship empty. The crawler
pulls course outlines + hole geometry from OpenStreetMap (Overpass) and
enriches course metadata from OpenGolfAPI; per-tee course rating + slope
are then backfilled from GolfCourseAPI. Service-role only.
SUPABASE_URL=<your-url> \
SUPABASE_SERVICE_ROLE_KEY=<your-service-role-key> \
pnpm crawl:courses --source osm-first
# One state for a quick smoke test
pnpm crawl:courses --source osm-first --states OK
# Resume / status
pnpm crawl:courses --statusFull US (50 states + DC) is roughly 10–15 hours. The crawler is
resumable via the crawl_state table — re-run to pick up where it
left off. See the header of scripts/crawl-courses.ts
for all flags.
# Web (http://localhost:5173)
pnpm --filter web dev
# Mobile — Expo Metro bundler, scan the QR code with the Expo Go app
cd apps/mobile
npm run devMobile uses Expo CNG — android/ and ios/ are regenerated on every EAS
build, so don't hand-edit native files.
cd apps/mobile
npx eas-cli build --platform android --profile developmentProfiles in eas.json: development, preview, production.
pnpm typecheck # tsc -b across the workspace
pnpm test # Vitest in @oga/coreapps/
web/ # Vite + React 18 web app
mobile/ # Expo + React Native (Android + iOS)
packages/
core/ # Pure TypeScript: math, stats, SG, Kalman, types
supabase/ # Generated types + client factory
supabase/
migrations/ # 0001_initial_schema.sql … numbered, sequential
functions/ # Supabase Edge Functions (practice plans, emails)
seed.sql # Demo courses + drill library seed
scripts/
crawl-courses.ts # Course crawler (OSM + OpenGolfAPI)
seed-demo.ts # Demo user + rounds of synthetic data
Drills, course data, bug fixes, and feature work all welcome. Branches
flow feature/* → dev → main; never push directly to dev or main.
CI must be green (typecheck + tests + web build + mobile typecheck)
before a PR is reviewed. See CONTRIBUTING.md for
the full workflow and code style.
OGA is free forever and runs on volunteer time + a small Supabase / Vercel / Mapbox bill. If it's helped your game, donations cover infrastructure costs:
MIT — © Contributors to the OGA project.