Building a Fitness App with React Native: A Complete Guide
Fitness apps have unique technical requirements that most mobile apps don't face: real-time data during workouts, wearable device integration, background tracking, and users who won't tolerate lag when they're mid-rep. Here's how to build one properly with React Native.
Why React Native for Fitness Apps?
React Native with Expo gives you native performance on both iOS and Android from a single codebase. For fitness apps specifically:
- Native modules for HealthKit (iOS) and Health Connect (Android)
- Background execution for step counting and GPS tracking
- Smooth animations at 60fps for workout timers and progress charts
- 50% less development cost compared to building native apps separately
The apps we build at Marketplace Labs typically ship to both platforms in 3-4 months, versus 6+ months for separate native builds.
Core Architecture
A fitness app needs three layers working together:
1. Real-Time Workout Engine
During active workouts, users expect instant feedback. Structure your state management accordingly:
// Use Zustand for workout state - simpler than Redux, fast enough for real-time
import { create } from 'zustand';
interface WorkoutState {
isActive: boolean;
elapsedSeconds: number;
currentHeartRate: number | null;
reps: number;
sets: CompletedSet[];
startWorkout: () => void;
recordRep: () => void;
updateHeartRate: (bpm: number) => void;
}
export const useWorkoutStore = create<WorkoutState>((set) => ({
isActive: false,
elapsedSeconds: 0,
currentHeartRate: null,
reps: 0,
sets: [],
startWorkout: () => set({ isActive: true, elapsedSeconds: 0 }),
recordRep: () => set((state) => ({ reps: state.reps + 1 })),
updateHeartRate: (bpm) => set({ currentHeartRate: bpm }),
}));
2. Health Data Sync Layer
Never call HealthKit or Google Fit directly from components. Create an abstraction layer:
// services/healthService.ts
import AppleHealthKit from 'react-native-health';
import { initialize, readRecords } from 'react-native-health-connect';
export const healthService = {
async getStepsToday(): Promise<number> {
if (Platform.OS === 'ios') {
return this.getStepsFromHealthKit();
}
return this.getStepsFromHealthConnect();
},
async syncWorkout(workout: CompletedWorkout): Promise<void> {
// Write to both platforms' health stores
// This ensures the workout appears in Apple Health / Google Fit
},
};
3. Offline-First Data Layer
Gym basements have terrible signal. Your app needs to work offline:
// Use WatermelonDB for local-first storage
import { Database } from '@nozbe/watermelondb';
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
// Workouts are saved locally first, synced when online
const adapter = new SQLiteAdapter({
schema,
migrations,
jsi: true, // Enable JSI for better performance
});
Wearable Integration
Apple Watch
For Apple Watch integration, you have two options:
- HealthKit only - Read data the Watch already collects (steps, heart rate, workouts)
- watchOS companion app - Build a dedicated Watch app for real-time control
Most fitness apps start with option 1. It's simpler and covers 80% of use cases:
import AppleHealthKit, { HealthKitPermissions } from 'react-native-health';
const permissions: HealthKitPermissions = {
permissions: {
read: [
AppleHealthKit.Constants.Permissions.HeartRate,
AppleHealthKit.Constants.Permissions.StepCount,
AppleHealthKit.Constants.Permissions.Workout,
],
write: [AppleHealthKit.Constants.Permissions.Workout],
},
};
AppleHealthKit.initHealthKit(permissions, (error) => {
if (error) {
console.log('HealthKit permission denied');
return;
}
// Ready to read/write health data
});
Bluetooth Heart Rate Monitors
For Polar, Wahoo, and other Bluetooth HR monitors:
import { BleManager } from 'react-native-ble-plx';
const HEART_RATE_SERVICE = '180D';
const HEART_RATE_MEASUREMENT = '2A37';
// Scan for HR monitors and subscribe to measurements
Background Tracking
Step counting and GPS tracking need to continue when the app is backgrounded:
// app.json (Expo)
{
"expo": {
"ios": {
"infoPlist": {
"UIBackgroundModes": ["location", "fetch"],
"NSMotionUsageDescription": "Used to count steps during workouts"
}
},
"android": {
"permissions": [
"ACTIVITY_RECOGNITION",
"ACCESS_BACKGROUND_LOCATION",
"FOREGROUND_SERVICE"
]
}
}
}
On Android, you'll need a foreground service with a persistent notification. On iOS, use significant location changes or the pedometer API.
Performance Optimisation
Fitness apps live or die by performance. Users notice lag during workouts.
Workout Timer
Don't use setInterval for workout timers - it drifts. Use the device clock:
const [startTime] = useState(Date.now());
const [elapsed, setElapsed] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setElapsed(Math.floor((Date.now() - startTime) / 1000));
}, 100); // Update frequently, calculate from real time
return () => clearInterval(interval);
}, [startTime]);
Chart Rendering
For workout charts with hundreds of data points, use react-native-skia instead of SVG-based libraries:
import { Canvas, Path, Skia } from '@shopify/react-native-skia';
// Skia renders charts at 60fps even with 1000+ data points
Common Pitfalls
1. Ignoring Android fragmentation - Health Connect is only available on Android 14+ (or as a separate app on older versions). Have a fallback.
2. Not handling permission denial gracefully - Users who deny health permissions can still use the app for manual logging.
3. Draining battery with GPS - Use significant location changes for casual tracking, high-accuracy GPS only during active outdoor workouts.
4. Forgetting timezone handling - A user who travels and works out will have confusing data if you store everything in local time.
What It Costs
A fitness app with workout tracking, health integration, and basic social features typically takes:
- MVP (3-4 months): £40,000 - £60,000
- Full-featured (5-7 months): £70,000 - £120,000
The range depends on whether you need a Watch app, custom wearable integrations, or social/community features.
Next Steps
If you're planning a fitness app, the first decision is scope. Start with:
- One core workout type (strength, running, or HIIT)
- Basic health data integration (steps, workouts)
- Simple progress tracking
Then expand based on user feedback. We've seen too many fitness apps try to do everything at launch and ship nothing.
Need help scoping or building? Get in touch - we've shipped fitness apps for gyms, personal trainers, and wellness startups.

