
The Situation
A self-hypnosis and wellness app with a growing audio catalogue in five languages, a subscription business, and a small founding team. They needed one engineering partner to own the app and its backend over the long term, including a full rebuild when the old codebase could no longer keep up.
The Constraint
New audio content and features had to ship continuously while a large existing user base stayed stable. Over five years that meant keeping up with OS and framework changes on iOS and Android without breaking subscriptions, downloads, streaks or progress that members had built up. The backend also had to keep growing within AWS’s hard deployment limits.
What we did
We own the iOS and Android app and the serverless backend behind it.
In late 2025 we rebuilt the app on React Native 0.82 and React 19, with a typed design system covering light and dark themes and five languages. We chose a clean rebuild over upgrading the old codebase one version at a time, because the old one was too far behind to upgrade cheaply.
We moved favourites, downloads, achievements, challenges, the mood diary and sobriety tracking into separate stores, instead of keeping everything in one shared state object with more than 50 actions. Logging out now clears every store, so one user’s data can’t carry over to the next account on the same phone.
On the backend, the main AWS stack reached CloudFormation’s hard limit of 500 resources. A common plugin would have split it automatically, but it would have deleted and recreated all 19 database tables. We added a separate stack on the same API instead, and no data was touched.
Our content tool previews sessions by running the app’s own display rules against a frozen copy of the catalogue. The preview stays accurate because we test it against the app rather than rewriting the logic by hand.
Content is cached and versioned, so phones refetch only what changed and keep the old copy if a refetch fails. Sessions can be downloaded and played fully offline.
Every pull request gets a written review that sorts issues into blockers, should-fix and cleanup before it merges.
-1.png)
-1.png)
-1.png)
The trade-off
In August 2026 we moved audio playback to Track Player 5. Within days we found problems with it on real devices, so we went back to version 4 while we fixed them, and released version 5 again a few days later. We made a similar choice with listening streaks. We count streak days in UTC, and sessions played offline don’t count toward them yet. Counting them would mean syncing listens after the fact, so we left that out until we could do it without breaking streaks people already have.
Outcome
| Metric | Value | Source | Date |
|---|---|---|---|
| Monthly active users | 100,000+ | Client analytics | Around five |
| Years maintained | Around five | Delivery records | Around five |
| Pull requests reviewed and merged since rebuild | 128 | Repository history | Nov 2025 to Oct 2026 |
| Languages | 5 (EN, ES, FR, DE, NL) | App source | Oct 2026 |
| Backend functions | About 130 serverless functions, 19 tables | Backend records | Oct 2026 |
| Current Android build | 3.0.573 | Release records | Oct 2026 |
What we would do differently
We would set up analytics identity on the first day. An audit in 2026 found that every analytics event was anonymous, with data stuffed into event names instead of properties. That made funnels and retention cohorts impossible until we fixed it. Now user identity and event structure are agreed before the first screen ships.
More work
See all work →Ready when the work has to be right the first time.
A 30-minute scoping call with a senior engineer, designer or growth lead. You will leave with a written view of scope, risks and a realistic timeline, whether or not you hire us.
12 years40+ shipped products6 industries
Karachi and Sharjah
.png)
.png)