Skip to main content

Case Study

Puber: An Ultramarathon Support App, Built End to End

Pacers, crew, and a per-race board for the 100-mile world. Built end to end, not yet shipped.

In ProgressMay 2026 - PresentSolo Developer & Designer

Updated May 12, 2026

Currently BuildingExpo + Supabase + Next.jsSafety as ArchitectureiOS + Android Target

The ultra world runs on group texts

100-mile trail races are team sports disguised as individual ones. Every runner needs pacers (who run alongside them through overnight mountain segments) and crew (who manage aid stations, gear, nutrition, medical). The coordination happens on Facebook groups, group texts, and word of mouth.

That system breaks down exactly when it matters most: a crew member drops out two days before a race, a runner needs a night-segment pacer in a town they have never visited, a solo woman runner wants a vetted pacer rather than a stranger from a forum. Puber exists to replace that patchwork with a real product.

Puber connects 100-mile trail runners with pacers and crew, plus a per-race community board for coordinating rides, lodging, drop bags, and last-minute replacements. The name is deliberate: a brand-reclamation play to own its meaning in the running world.

~25

Postgres migrations

14

Deno edge functions

RLS

on every table

10 races

84 aid stations seeded

Built like a real product

Puber is not a prototype or a design exercise. It is a full-stack build: mobile app, admin/ops console, and backend, all running end-to-end on the iOS simulator against a clean supabase db reset. Three surfaces, one codebase discipline.

Mobile

  • Expo SDK 54 + React Native 0.81
  • Expo Router 6, Zustand + TanStack Query
  • Mapbox with supercluster + GPX parsing
  • react-native-reanimated 4
  • MMKV + expo-file-system offline cache
  • 9-step onboarding with UltraSignup import
  • Stripe Identity selfie-liveness verification

Backend

  • ~25 Postgres migrations, RLS on every table
  • 14 Deno edge functions (push, auth, Stripe, safety)
  • 5 pg_cron jobs (escalation, staleness, expiry)
  • 6 realtime-published tables, 4 storage buckets
  • Match state machine as a BEFORE-UPDATE trigger
  • Block-aware RLS + SECURITY DEFINER helpers

Admin / Ops Console

  • Next.js 15 App Router + shadcn/ui
  • TOTP + WebAuthn passkey auth
  • 7 roles x 28 capabilities RBAC
  • Append-only audit logging, rate limiting
  • 17 route handlers, Recharts dashboards
  • Race-data editor with mandatory source citations

The match state machine alone tells the story: implemented as a Postgres BEFORE-UPDATE trigger walking through requested pending rules_acknowledged confirmed active completed, with side-exits to cancelled, admin cancellation, and expiry, plus a block-auto-cancel trigger.

Safety is the architecture

Safety is a design requirement, not a feature flag.

The ultra community includes solo women running through remote mountain segments at 2am with a stranger they met online. That scenario defined the safety architecture, not a product manager's backlog.

Gender-preference matching

Runners choose who they run with

Scheduled check-ins with escalation

3-minute pg_cron sweep

"Tell a friend" live-location sharing

Safety alerts via edge function

DV-safety options

Designed for women in vulnerable situations

Stripe Identity selfie-liveness verification is env-gated and ready: pacers verify their identity before they are matched with a runner they have never met.

Offline by necessity

Zero cell service in the canyons is the baseline, not the edge case.

The “Race Kit” is a per-race offline bundle cached to the device via MMKV and expo-file-system. Race rules, aid-station data, map tiles, and the full course GPX are available with no signal. A pg_cron job rebuilds the Race Kit manifest on the server; the app syncs when it has connectivity and serves locally when it does not.

This is not a nice-to-have. Leadville's Hope Pass, Hardrock's Virginius Pass, Western States' canyons: these are the segments where crews and pacers most need accurate data, and they are the segments with the least signal. The app was designed for 3am in a canyon with no bars.

Brand system

The brand

The logomark is a stylized jackrabbit mid-bound: lean, athletic, ears swept back. Confident and a little wild, not cute, not cartoon. The hare is the pacer who sets the pace. Voice: rugged but refined, calm confidence, dawn-on-the-trail, soul sport.

Puber app icon: white running-jackrabbit logomark on Elevation Blue
Puber logomark: white running-hare silhouette on transparent background
Puber brand system board: brand overview, logo system, color palette, typography, photography style, UI elements, and app-icon variants
Puber icon system board: logomark, wordmark, tagline, app-icon variants, icon sets, and UI mockup

Elevation Blue

#007AFF / Primary

Summit Navy

#0B1D2A / Dark base

Trail Orange

#FF6B00 / Energy

Peak Yellow

#FFC107 / Finisher gold

Alpine Mint

#00D1B2 / Success

Where it's headed

v1 is built end-to-end and running locally. Target: iOS and Android launch for the 2026 marquee 100-mile season (Western States, Hardrock, Leadville, Cocodona, Bear, Wasatch). The database is seeded with 10 marquee races, 46 source-cited rules, and 84 aid stations.

What ships next:

App Store screenshots and marketing assets
Designer-redrawn SVG logomark (current marks are AI rasters)
iOS 18 tinted icon variants
Production Supabase, Mapbox, Apple, Stripe, and Twilio credentials
EAS build configuration
Legal review and App Store submission

This is not a weakness to hide. It is the honest remaining distance between a working local build and a live product in runners' hands.

Built for the people who run through the night so someone else doesn't have to run alone.

Tech Stack

Mobile

Expo SDK 54React Native 0.81Expo Router 6@rnmapbox/mapsreact-native-reanimated 4react-native-mmkvexpo-notifications

Frontend

ZustandTanStack QueryTypeScriptNext.js 15 (Ops Console)shadcn/ui

Backend

Supabase (Postgres + RLS)Deno Edge Functionspg_cronSupabase RealtimeSupabase StorageWebAuthn + TOTP (Passkeys + MFA)Stripe Identity

Tooling

EAS BuildJest + Testing Library

Want to discuss the architecture?

Get in Touch
Puber: An Ultramarathon Support App, Built End to End — Jeff Michael Johnson