Expo + HealthKit Fitness Stack

The fitness-ready stack: Expo, Supabase, HealthKit on iOS, Health Connect on Android, push for streaks. Ships a real fitness app in 3 weekends.

Stack/Expo + HealthKit Fitness Stack

Starter Kit

Expo + HealthKit Fitness Stack

Expo + Supabase + HealthKit ships a real fitness app in 3 weekends. What it covers, timezone-aware streak logic, and the Apple review rules.

What this stack is good for

Fitness, wellness, habit tracking, anything that wants to read health data from the phone and keep a retention loop alive with pushes. Native iOS and Android. Supabase holds the non-health data (user state, workout sessions, streaks).

The pieces

  • Expo + React Native with expo-dev-client because HealthKit needs a native module and Expo Go will not work.
  • react-native-health for HealthKit read.
  • Android Health Connect via a parallel module or a thin native wrapper.
  • Supabase for auth, user streaks, workout session metadata.
  • Expo Notifications for streak-about-to-break pushes.
  • NestJS if you want a server-side streak calculation and a quota on AI coaching features.

Real build time for a v1

Fitness app with workout logging, HealthKit step/energy read, streak logic, and streak-save push:

  • Auth + user streak table in Supabase: ~4 hours.
  • Workout logging screen: ~5 hours.
  • HealthKit integration + permissions: ~5 hours.
  • Streak logic (timezone-aware) + daily recompute: ~6 hours.
  • Push notification + scheduling: ~4 hours.
  • App Store review fixes (HealthKit reason string is the usual one): ~3 hours.
  • Screenshots + submission: ~5 hours.

About 32 hours total. Shipped one myself, 3 weekends.

What the health layer looks like

Three reads cover almost every fitness v1:

  1. Steps for today and last 7 days.
  2. Active energy for last 7 days.
  3. Workout sessions for the last 30 days.

Everything else is computed from those three. Do not start with 20 data types.

Streaks done right

Streaks are harder than they look. The edge case that breaks every naive implementation is timezones. A user in Tokyo logs a workout at 11pm local. Your server sees 2pm UTC. If you store the date in UTC the streak breaks when they cross midnight local.

Fix: store streak dates in the user local day. The Postgres function takes the user timezone (tracked in their profile) and computes current_date AT TIME ZONE user_tz.

Push scheduling

Streak save push fires at N minutes before the end of the user local day if they have not logged today. Batched nightly, filtered by user timezone. Not a cron per user — one cron per hour that handles everyone whose local day is about to end.

What AI App Factory ships

  • Supabase schema for profiles with timezone, workouts, streaks.
  • Postgres function recompute_streak that is timezone-aware.
  • React Native workout logging screen.
  • HealthKit permissions with App Store-safe reason strings.
  • Push scheduler for streak-save pushes.
  • Expo config plugin for the HealthKit entitlement.

See pricing

Get this stack today.

One-time purchase. Full-stack boilerplate + 11 AI agents. No subscription.

AI App FactoryStackExpo + HealthKit Fitness Stack