Ealthiness: Building a Health and Fitness App in React Native
Guided workouts, live run tracking, mood graphs and coaches in one mobile app. A look at how Ealthiness is built and what fitness apps get wrong.
Ealthiness is a mobile health and fitness companion. It guides people through workouts, tracks their runs live, shows how their mood and activity move over time, and connects them with coaches. The goal is simple to state and hard to deliver: turn everyday movement into progress people can actually see.
We designed and built the app experience end to end. This post covers the architecture and the practical decisions behind a fitness app that people keep opening after the first week.
The stack
The app is React Native with Expo, using TanStack Query for server state. The backend is NestJS with PostgreSQL, Redis for caching and Elasticsearch for search across exercises and content, deployed on Railway. Payments are split by platform reality: RevenueCat manages in-app subscriptions on iOS and Android, and Stripe handles payments on the web.
We chose React Native for the same reason we usually do: one team, one codebase, both stores, and a fast path into native code for the parts that need it. In a fitness app, those parts are location, motion and background execution. Our general approach is in building great React Native apps.
TanStack Query does more work in an app like this than it first appears. Workouts, history, mood entries and coach messages are all server state with different freshness needs: an exercise library can be cached for hours, today's activity should refresh when the app comes to the foreground, and a mood check-in should appear in the graph the moment it is saved. Declaring those rules per query, with optimistic updates for the user's own input, keeps the app feeling instant without a hand-written cache layer.
Live run tracking
Run tracking is the feature that most separates a fitness app from a content app, and it is mostly about respecting the phone. The difficult parts are not drawing a line on a map; they are:
- Background location that keeps recording when the screen is off, with the permission prompts and store justifications that requires.
- Noisy GPS. Raw points jump around, especially near tall buildings. Filtering out implausible jumps before computing distance and pace matters more than any UI polish.
- Battery. Sampling as often as possible feels accurate and drains a phone in an afternoon. The sampling rate has to match the activity.
- Losing nothing. A run is recorded locally first and synced afterwards, so a dropped connection mid-run never costs the user their workout.
The screen a runner sees mid-run should be the simplest in the app: elapsed time, distance, current pace, and large controls that work with sweaty hands. Everything else — splits, the route map, comparisons with previous runs — belongs on the summary afterwards, computed from the cleaned track rather than the raw one.
Guided exercises and content
Guided workouts are a content problem as much as a code problem. Exercises, sets, timings and media need to be authored by people who are not engineers, then delivered quickly to the phone. Keeping that content in the backend, searchable through Elasticsearch, means the team can add and adjust workouts without shipping an app update. Media is cached on the device so a workout in a gym basement with no signal still plays.
The workout player itself has to survive real life. A phone call arrives, a notification slides in, the user switches to their music app between sets. The player keeps its own state — current exercise, set, remaining time — so it can be paused and resumed cleanly instead of restarting the session or losing progress.
Mood graphs, insights and coaches
Ealthiness tracks more than movement. Users log mood, and the app shows mood and activity over time side by side. The value is in the pairing: a person can see for themselves how a week of regular movement lines up with how they felt.
Two principles guided this part. First, keep logging fast — a check-in that takes more than a few seconds stops happening. Second, be careful with conclusions. The app shows patterns; it does not diagnose. Health data is sensitive, so it is stored with that in mind, access is scoped to the user and the coaches they choose to connect with, and nothing is shared beyond that.
Coaches in the loop
The coaching side connects users with real people who can see their progress and adjust their plan. This is where the backend design matters: permissions are explicit and revocable, a coach sees only the users who have connected with them, and the data model treats that relationship as something the user controls. TanStack Query on the client keeps both views — the user's and the coach's — fresh without the app hammering the API.
Subscriptions without surprises
Subscription logic is the area where fitness apps most often get support tickets. Using RevenueCat for in-app purchases means receipt validation, renewals and cross-platform entitlements are handled by a service that does only that, and the backend receives a single, consistent view of whether a user is subscribed. Stripe covers web payments. The entitlement check lives on the server, so the app never decides on its own what a user has paid for.
The rest is store hygiene that is easy to postpone and painful to retrofit: a working restore-purchases button, clear wording on renewal and cancellation, and a defined answer for what happens to a user's history when a subscription lapses. Deciding those up front saves a review rejection and a stream of confused emails.
What we would repeat
- Record locally first, sync later — especially for anything the user physically worked for.
- Treat GPS and sensor data as noisy input that needs filtering, not as truth.
- Keep workout content on the server so it can change without a release.
- Make health data access explicit, scoped and revocable from day one.
- Let a dedicated service own in-app subscription state.
Building a health or fitness product?
Our mobile app development team builds React Native apps like Ealthiness, from the first prototype to store release and the backend behind it. See the Ealthiness project or contact us.
