Skip to main content
All postsMobile

Three apps, one product: building multi-role mobile experiences

7 min read

When we built Rainbow Lifts' mobile suite, we shipped three separate apps — customer, field engineer, and admin — from a single codebase. Here's what that decision saved us and where it got complicated.

When Rainbow Lifts approached us, they had a single problem that had three completely different faces. Customers needed to raise service requests and track when the engineer would arrive. Field engineers needed job lists, route guidance, and a way to close a ticket without calling the office. Management needed a live view of every active job, every technician, and every escalation.

Three user groups. Three distinct workflows. One company.

The architecture decision

We could have built a single app with role-based views. But role-based apps carry hidden complexity — navigation that conditionally shows and hides, permissions that gate every screen, and an onboarding experience that has to serve everyone equally well. We have seen this approach get unwieldy fast.

Instead we built three thin apps from one shared codebase: a customer app, a field engineer app, and an admin app. Each app has one audience, one set of tasks, and one mental model. React Native with Expo let us share all business logic, API calls, and UI components across all three while each app's navigation tree stayed purpose-built for its user.

What the split saved us

The customer app is small — raise a request, view its status, call the engineer. That simplicity made the onboarding trivial to design. We were not fighting a "but what if the user is also an engineer" edge case at every screen.

The engineer app is offline-first by necessity. Engineers go into basements and lift shafts where connectivity drops. We built a local queue for every action — job acceptance, site notes, photo uploads, ticket close — so the app works perfectly with no signal and syncs silently when it reconnects. That level of offline care would have been much harder to retrofit into a combined app.

The admin app is data-dense: live job maps, escalation feeds, team availability. We built it with a tablet-first layout that would have felt crowded and out of place inside an app designed for a customer's phone.

Where it got complicated

Shared code is not free. When we changed an API response shape to support the engineer app's offline sync, we had to audit every place that response was consumed across all three apps. A change that "should have been simple" touched more files than expected.

Push notification routing was also tricky. A single Firebase project sends to all three apps, but the notification payload has to route to the right app. We ended up encoding the target audience in the notification data and filtering at the client — inelegant but reliable.

What we would do differently

We would invest earlier in a monorepo toolchain. We managed shared packages manually for too long. If we were starting today we would set up a proper workspace from day one and treat the shared layer as a first-class library with its own tests.

Multi-app projects reward upfront structure more than any other project type. The apps grow apart faster than you expect, and the shared code is the only thing keeping the maintenance cost manageable.

Keep reading

Reach us directly — no forms, no wait

Let'stalk.

Drop us a message or call us directly. We reply to every enquiry — usually the same day.