Rebuilding a Fitness Community App From Scratch in React Native: A 14-Week Build Log
What a real cross-platform app schedule looks like: the scope we cut, the order features landed, and where the iOS-only time actually went.
2026-08-15 · By Filip Lauc
What Was Being Replaced: Spreadsheets, WhatsApp, and Manual Payments
MOVE & MEET ran a London social fitness community on spreadsheets, group chats, and manual payment reconciliation. Class rosters lived in shared sheets, sign-ups arrived by message, partner studios confirmed attendance verbally, and someone matched bank transfers to names by hand every week. The app had to absorb all four of those loops.
That starting point matters more than the tech choice, because it defines what the first version has to do on day one. A community that already had paying members and scheduled classes could not ship a product that only did half the job. If booking worked but payment did not, the operations team would still be reconciling by hand, and the app would have added work rather than removed it.
So the v1 boundary was drawn around one complete loop: a member finds a class, books it, pays for it, shows up, and a partner venue marks them present. Everything that sat outside that loop, however attractive in a design review, was pushed to a later release. The 14 weeks below are what it took to close that loop on both platforms with a small team.
The v1 Scope Cut: What We Deliberately Left Out and Why
Roughly a third of the originally discussed feature list was cut before week one. The rule we applied was simple: if a feature did not either close the book-pay-attend loop or remove a manual step from the operations team's week, it was not in v1. Cutting early is what kept the schedule at 14 weeks rather than 24.
Scope cuts are easier to defend when they are written down with a reason attached. Below is the list we agreed on, along with the reasoning that survived later requests to reopen it. Two items came back in the first post-launch cycle, which is the point: cutting is sequencing, not deletion.
The most contested cut was in-app chat. It is the feature that sounds most natural for a community product and is also the one that adds moderation, notification, retention, and abuse-reporting obligations to a v1. Existing group chats already worked. Rebuilding them badly inside an app would have been a downgrade for members and a permanent maintenance cost for the team.
- • Cut: in-app chat and direct messaging. The community already had working group chats, and moderation plus push infrastructure would have added weeks with no operational gain.
- • Cut: social feed with posts, likes, and comments. High design cost, zero effect on booking or reconciliation. Revisited after launch.
- • Cut: gamification, streaks, and badges. Retention mechanics need real usage data to design against, and there was none yet.
- • Cut: in-app class creation for partner venues. Handled through the back office in v1, with partners emailing schedule changes, because the admin surface was already being built.
- • Cut: Apple Watch and health-data integration. Requires HealthKit entitlements, privacy review, and a native module for a feature nobody had asked to pay for.
- • Kept: waitlists. Not obviously v1, but classes filled and the manual waitlist was one of the worst spreadsheet chores.
- • Kept: cancellation windows with automatic refunds or credits. Removing this would have moved work back onto the operations team.
Weeks 1 to 14: The Order Features Actually Landed
Features landed in dependency order, not in order of visibility. Auth first, then the class catalogue and booking, then payments, then partner check-in, then polish and store preparation. Nothing that depended on an unfinished layer was started early to look productive in a demo.
The reason for this order is that each stage produces something the next stage needs. Booking is meaningless without an identity to attach it to. Payments are meaningless without a booking object to charge against. Partner check-in is meaningless without a confirmed, paid booking to verify. Building in this order means every week ends with something demonstrably working end to end, rather than three half-features waiting on each other.
Design ran roughly two weeks ahead of implementation throughout. Screens were finalised for the stage being built next, which meant designers were never blocked and engineers were never guessing. The back office and partner dashboard were built on the web in parallel by a separate track, because the app depends on data that only exists once an admin can create it.
- • Weeks 1 to 2: Project setup, navigation shell, design system components, Firebase project structure, data model for users, classes, bookings, and venues. First TestFlight build went out at the end of week 2 with nothing but navigation, purely to prove the pipeline.
- • Weeks 3 to 4: Authentication, sign-up, profile, and membership state. Email plus Apple and Google sign-in. Sign in with Apple is non-negotiable once third-party sign-in exists, so it was built in the same pass rather than bolted on later.
- • Weeks 5 to 7: Class catalogue, schedule browsing, venue pages, filtering, and the booking flow including capacity limits and waitlists. This was the largest single block of shared code.
- • Weeks 8 to 9: Payments, memberships, class packs, cancellation windows, refunds and credits, plus receipts. Webhook handling and reconciliation logic on the backend took longer than the app screens.
- • Week 10: Partner check-in. A separate authenticated surface where venue staff see the day's roster and mark attendance, with QR-based confirmation as the fallback path.
- • Week 11: Push notifications, booking reminders, deep links, and empty and error states across the app. This is the week that removes the last of the manual reminder messages.
- • Week 12: Store preparation. Screenshots, listings, privacy nutrition labels, data-safety form, account deletion flow, and a full pass on permission prompt copy.
- • Week 13: Submission, rejection, fix, resubmission, approval. Details in the next section.
- • Week 14: Google Play release, staged rollout, monitoring, crash triage, and handover of the back office to the operations team.
Submission, the First Rejection, and How Many TestFlight Builds It Took
The first App Store submission went in during week 13 and was rejected on the first review. The cause was the account and data deletion requirement under App Store guideline 5.1.1(v): the app allowed account creation but offered no in-app way to delete the account and associated data. The fix took under a day, and the resubmission was approved on the next review cycle.
This is the single most common avoidable rejection for a first-time consumer app, and it is worth stating plainly because it is trivially preventable. If your app creates accounts, it needs an in-app deletion path that actually deletes, plus a clear description of what is retained and why. We now build that flow during the auth stage rather than during store prep, which is why it exists in week 3 on any schedule we run today.
Across the 14 weeks, the app went through roughly 30 TestFlight builds, with a heavy cluster in weeks 7 through 12 when real members were testing booking and payment flows on their own devices. Internal builds went out several times a week; external TestFlight groups received a build at the end of most weeks. Android testing ran through an internal testing track on Google Play on a similar cadence. Google Play review was faster and passed on the first attempt, but the data safety form and the target API level requirements needed their own dedicated pass.
Native Modules: What We Added and What We Refused
Every native module is a permanent maintenance obligation across two platforms and every future React Native upgrade. The rule we applied was that a module had to be either unavoidable for a core flow or already maintained by a major vendor. Four made the cut. Several tempting ones did not.
The camera is the clearest example of the tradeoff. Partner check-in needs QR scanning, which needs camera access, which needs a native module, a permission prompt, a privacy manifest entry, and a fallback for members who deny the permission. That cost was accepted because check-in is a core loop. Photo filters, video upload, and background location, all discussed at various points, were not accepted, because each carried a similar or larger cost against a feature that was already cut from v1.
Avoiding a native module is not always the cheaper option, and pretending otherwise leads to bad engineering. Payments are the counter-example: we used a maintained vendor SDK with native components rather than a webview checkout, because native payment sheets, Apple Pay, and 3D Secure handling in a webview produce worse conversion and worse failure modes. The test is not native versus not native. It is whether the module is core, maintained, and understood.
- • Added: payments SDK with native payment sheet support, including Apple Pay and Google Pay.
- • Added: camera and QR scanning for partner check-in.
- • Added: push notifications with deep-link routing into class and booking screens.
- • Added: authentication providers, including Sign in with Apple.
- • Avoided: HealthKit and Google Fit integration, deferred with the wearables feature.
- • Avoided: background location, which would have triggered additional review scrutiny and battery complaints for a feature nobody had validated.
- • Avoided: custom video or media processing, replaced by hosted media and standard players.
- • Avoided: any unmaintained community package touching a core flow. Two candidates were rejected for having no release in over a year.
The Real Cost Split Between Shared Code and Platform-Specific Work
The great majority of the code was shared across iOS and Android. Platform-specific engineering time, meaning code that only ran on one platform plus store-specific process work, was a comparatively small share of the build, and most of it was concentrated in two areas: payments and native integrations, and the store submission process itself.
Where iOS specifically ate time was rarely in writing Swift. It was in review-driven requirements: privacy nutrition labels, the privacy manifest, permission prompt copy that has to explain purpose in the user's terms, Sign in with Apple parity, and the account deletion requirement that caused the rejection. Android time went into the data safety declaration, target API level compliance, back-button and navigation behaviour, and testing across a wider device and OS spread than iOS demands.
The practical planning lesson is that cross-platform does not mean one platform's worth of work. It means one codebase and two release processes. When someone estimates a React Native project as if the second platform is free, the schedule slips at exactly the point where slipping is most expensive: the final two weeks, when store reviews and marketing dates are already committed. Budget the store work explicitly, as its own line, from the start.
Key Takeaways
- • A 14-week schedule for a booking-and-payments app is realistic only if roughly a third of the wish list is cut before week one, with each cut written down and justified.
- • Build in dependency order: auth, then catalogue and booking, then payments, then partner check-in, then notifications and store prep.
- • The first App Store rejection was the account deletion requirement under guideline 5.1.1(v). Build the in-app deletion flow during the auth stage, not during store prep.
- • Native modules were limited to payments, camera and QR, push, and auth providers. Anything unmaintained or tied to a cut feature was refused.
- • Cross-platform means one codebase and two release processes. The second platform is not free, and the store work belongs in the plan as its own line item.
The full picture of the platform this build log covers, including the website, back office, and partner dashboard, is in our MOVE & MEET case study, which took a London fitness community from spreadsheets to a 4.9-star App Store app.
Frequently Asked Questions
How long does it take to build a mobile app from scratch with a development agency?
A focused consumer app with authentication, a booking or catalogue flow, payments, and push notifications typically takes 12 to 16 weeks to first release with a small dedicated team. That range assumes a disciplined v1 scope, designs staying about two weeks ahead of implementation, and a client who can make decisions within days rather than weeks. Adding chat, social feeds, or health-device integrations usually pushes it past 20 weeks.
Should I build my app in React Native or go fully native?
React Native is the right default when the app is primarily forms, lists, media, and network calls, which describes most booking, marketplace, commerce, and community apps. Go fully native when the product depends on sustained heavy graphics, low-level device hardware, or platform-specific interfaces like complex widgets and watch apps. A large share of code stays shared in React Native, but the second platform still costs real time in release process and testing.
What are the most common reasons an app gets rejected from the App Store?
The most frequent avoidable causes are a missing in-app account deletion path when the app supports account creation, incomplete or inaccurate privacy nutrition labels, permission prompts that do not clearly explain why access is needed, missing Sign in with Apple when other third-party sign-in options are offered, and demo accounts that reviewers cannot log into. Most of these are preventable in a single pre-submission checklist pass.
How many beta builds should I expect before launching an app?
Expect a build going to internal testers several times a week, and a build to external beta testers roughly weekly once real flows are testable. Over a three-to-four month project that commonly totals somewhere between 20 and 40 TestFlight builds, with the highest volume in the weeks when payments and other money-touching flows are being validated on real devices.
Can an agency build both the mobile app and the admin back office in the same project?
Yes, and it is usually the better arrangement, because the app cannot show anything until an admin can create it. In the MOVE & MEET build, the back office and partner dashboard were developed on a parallel web track sharing the same data model and backend, so class data, venues, and memberships existed for the app to consume as each feature was built.
Sources
Written by
Filip Lauc
CEO, Jaspero
Filip Lauc is the CEO of Jaspero, a software development agency based in Osijek, Croatia. A full-stack JavaScript developer with over a decade of experience across Angular, Svelte, and Node.js, he leads Jaspero's work as a long-term embedded engineering partner for clients like GlycanAge, where his team has served as the dedicated engineering team for six years.
Let's Build Together
Your vision,
our expertise.
From AI integration to full-stack development, we turn ambitious ideas into products that perform.