I'm part of the running community — people who lace up every morning, track every mile, and obsess over their Strava stats. Running apps today are incredible at what they do. Strava tracks your routes. Nike Run Club coaches your training. MapMyRun logs your history.
But here's the gap I kept noticing: once you finish a run, what do you actually own? A line on a map and some numbers. There's no lasting mark on the world. No reason to go back to the same streets, no incentive to explore new ones, and no connection between your physical effort and the neighborhoods you run through every day.
Runners already feel ownership over their routes — "that's MY morning loop" — but nothing on the map reflects that. I wanted to change that.
What I Built
TerraRun — a territory capture running app where every closed loop you run becomes your turf on the map.
The concept: go for a run, close a loop (your route connects back to where you started), and the enclosed area fills in with your color on a shared public map. That's your territory now. Other runners can reclaim it by running the same loop. The more territory you hold, the higher you rank.
Think of it as Strava meets king-of-the-hill — your runs aren't just logged, they're staked.
Key features:
- Territory Capture — Run a closed loop, and the exact shape of your route becomes claimed territory on the map. Not a grid, not circles — the actual polygon of your run, just like Strava route art.
- Live Run Simulation — A "Watch Demo Run" button animates a runner tracing an irregular street-level route in real-time. When the loop closes, the territory fills in with a capture animation.
- Share Card — After capturing territory, a share modal pops up with your route shape rendered as a graphic, plus your stats (distance, time, pace, area). One tap to share on WhatsApp, Telegram, X, or copy the link.
- Interactive Map — Full-screen Mapbox map with 4 styles (Dark, Streets, Satellite, Outdoors), 3D toggle, territory click popups showing owner and capture date.
- Leaderboard — Runners ranked by territory held. Top 3 podium. Filters for All Time, This Week, Nearby.
- Profile Dashboard — Your stats, achievement badges, active streak, and activity feed.
- Sponsor Zones — Brands (Nike, Adidas, Gatorade, Under Armour) place zones on the map. Run through them to unlock real coupon codes. Runners get rewarded. Brands get literal foot traffic.
What makes this different from existing apps:
| Strava | Nike Run Club | TerraRun | |
|---|---|---|---|
| Tracks runs | ✅ | ✅ | ✅ |
| Social competition | Segments only | Challenges | Territory wars |
| Map ownership | ❌ | ❌ | Your runs claim real map area |
| Reason to re-run a route | ❌ | ❌ | Defend your territory |
| Brand engagement | Ads | Ads | Physical sponsor zones you run to |
Demo
Live deployment: TerraRun on Vercel
Code
TerraRun — Run. Loop. Conquer.
A territory capture running app where every closed loop you run becomes your turf on the map. Built for the DEV Weekend Challenge (Feb 27 – Mar 2, 2026).
Live Demo: terrarun-dev.vercel.app
Video Demo: youtu.be/Cr7n3qfzARM
The Idea
Running apps like Strava and Nike Run Club are great at tracking — but once a run is done, all you have is a line on a map. TerraRun changes that. Run a closed loop, and the enclosed area fills in as your territory. Others can reclaim it by running the same loop. Every neighborhood becomes a game board.
Features
- Territory Capture — Closed-loop runs become filled polygon territories on the map, matching the exact shape of your route
- Live Run Simulation — Animated demo run traces an irregular street-level path, captures territory on loop close
- Share Card — Post-capture modal with route shape graphic, stats (distance, time…
Project structure:
terrarun/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── page.tsx # Landing page
│ │ ├── map/page.tsx # Main interactive map
│ │ ├── leaderboard/page.tsx
│ │ ├── profile/page.tsx
│ │ └── sponsors/page.tsx
│ ├── components/
│ │ ├── map/ # MapView, TerritoryLayer, RunSimulation, ShareModal
│ │ ├── landing/ # Hero, Features, HowItWorks
│ │ ├── layout/ # Navbar with mobile bottom nav
│ │ ├── leaderboard/ # LeaderboardTable
│ │ └── profile/ # ProfileStats
│ ├── lib/
│ │ ├── mock-data.ts # 6 users, 7 territories, 4 sponsors
│ │ ├── territory.ts # Polygon territory generation with Turf.js
│ │ ├── h3-utils.ts # H3 hex utilities (available for future use)
│ │ └── constants.ts # Map config, styles, colors
│ ├── store/
│ │ └── useMapStore.ts # Zustand state management
│ └── types/
│ └── index.ts # TypeScript interfaces
How I Built It
Tech Stack
| Technology | Purpose |
|---|---|
| Next.js 16 | Framework — App Router, SSR, file-based routing |
| React 19 | UI rendering |
| TypeScript | Type safety across the entire codebase |
| Tailwind CSS 4 | Styling — dark theme, glass morphism effects |
| Mapbox GL JS 3 + react-map-gl 8 | Interactive map rendering with 4 style modes |
| Turf.js 7 | Geospatial calculations — polygon area from GPS coordinates |
| Framer Motion 12 | Animations — page transitions, capture celebrations, share modal |
| Zustand 5 | Lightweight state management for map and simulation state |
| Lucide React | Icon system |
How the territory system works
The core mechanic: a runner's GPS route forms a closed polygon. When the loop closes, I use Turf.js to calculate the enclosed area in km², and render it as a filled GeoJSON polygon on the Mapbox map. The territory is the exact shape of the run — no grids, no approximations.
// Convert route points to a territory polygon
const ring = routePoints.map(p => [p.lng, p.lat]);
const poly = turfPolygon([ring]);
const areaKm2 = turfArea(poly) / 1_000_000;
Each territory stores: polygon coordinates, owner, color, area, capture date. Territories are rendered as GeoJSON with a 3-layer glow border effect (outer blur + mid blur + core line) for that neon territory look.
The run simulation
The demo run isn't a perfect circle — it's an irregular street-level route that zigzags through Central Park paths, because that's how real runs look. The animation:
- Runner marker moves along the route at running pace
- A trail polyline draws behind in real-time
- When the loop closes → territory fill animation + capture stats
- Share card appears with the route shape, stats, and social share buttons
Design decisions
- Polygons over hex grids — I initially built with H3 hexagons but realized runners follow streets, not grids. Polygon fills matching the actual run shape feel natural and look like the Strava route screenshots people already share.
- Dark theme default — Territory colors glow best on dark backgrounds. The glass morphism UI keeps it clean.
- Mobile-first — Bottom navigation bar, touch-friendly controls, responsive everything. Runners use phones.
- Share-first capture flow — The share modal appears immediately after capture because the screenshot moment is what drives virality in running apps.
Built in a weekend
This was built from scratch during the DEV Weekend Challenge window. The entire app — 5 pages, interactive map, run simulation, territory system, share flow — was designed, coded, and deployed within the challenge timeframe.
AI was used as a development tool throughout the process.
Run. Loop. Conquer. 🏃
Top comments (0)