Skip to content
Book a technical review
Aerial night view of a dense Mediterranean old town: tightly packed dark rooftops separated by narrow lanes, each lane lit by a line of warm orange streetlamps

One app, many services: building a super app for home services in Tunisia

Softwise built a home-services super app for a Tunis marketplace startup: cleaning, repairs, and delivery verticals in one native mobile app. Each vertical ships as an independent module behind a shared identity, wallet, and messaging core, so a new service line launches without touching the ones already live.

Context

The client and the problem

Anonymized by design: industry and city, not names. The shape of the problem is the point.

The client

A Tunis startup running three separate service brands: home cleaning, appliance repair, and small-parcel delivery. Three apps meant three store listings competing for the same users, three logins, and marketing spend split three ways.

The problem

Users who booked a cleaning never discovered the repair service, because it lived in a different app. The company wanted what regional users already expect from apps like Careem: one account, one wallet, many services. The engineering risk of a super app is the opposite one: a monolith where every vertical's release blocks every other's.

The constraints

Cash is still king. Most Tunisian customers pay cash, not card. A wallet-only design would have excluded the majority of the market, and card-on-file adoption had to be earned, not assumed.

Three live brands, one install window. The three existing apps kept running until their replacements shipped. The super app had to reach store parity with all three before any of them was retired.

App store review risk. Apple's guidelines on super apps made the modular architecture a submission requirement, not just an engineering preference: one binary, independently reviewable service modules.

Build

What we built

Decisions, not adjectives. Each one had an alternative we rejected.

A thin core, fat modules

The core owns exactly four things: identity, payments and wallet, notifications, and chat between customer and provider. Each service vertical is a self-contained module with its own screens, booking flow, and release cadence. The cleaning team's release cannot break delivery.

Native, not wrapped

Built natively for iOS and Android. Booking flows, maps, and provider tracking are the entire product experience, and a wrapper's jank is exactly where users abandon a checkout.

Payments for a cash-first market

In-app wallet with card top-up and cash-on-completion recorded against the same ledger, because most Tunisian customers still pay cash. Providers see one balance regardless of how the customer paid.

One account, three discovery surfaces

The home screen surfaces all verticals to every user, which is the actual commercial point of a super app: a cleaning customer becomes a delivery customer without a new install, login, or payment setup.

Provider-side operations

Cleaning crews, repair technicians, and courier fleets got their own provider app with job acceptance, scheduling, and earnings against the same shared ledger, so marketplace supply scaled with demand. A shared job-matching service handles assignment and scheduling for every vertical, so a new service line inherits dispatch rather than rebuilding it.

Home-services super app: modular architectureNative iOS and Android customer apps and a provider app sit on top of independently releasable service modules for cleaning, repairs, and delivery. Each module owns its screens, booking flow, and release cadence, and depends only on a deliberately thin shared core: identity, wallet and payments with a unified cash-and-card ledger, chat, and notifications. Provider crews and fleets see one balance regardless of how the customer paid. Hover or tap a component to trace its connections.ONE APP BINARY — MODULES RELEASE INDEPENDENTLYapp trafficapp trafficjob eventsbooks cleansbooks repairsrequests couriersassignmentsjob createdjob createdone ledgersettlementsaccept jobspersistencepayoutslive trackingCustomer iOSnative SwiftCustomer Androidnative KotlinProvider appcrews · technicians · couriersCleaning moduleown screens + release trainRepairs moduleown screens + release trainDelivery moduleown screens + release trainJob matchingassignment + schedulingShared core (deliberately thin)Identity · Wallet + payments · Chat · NotificationsUnified ledgercard top-up + cash-on-completion, one balanceCore APINode.jsPostgreSQLcore + module schemasCard gatewaytop-up + payoutsMaps + trackingprovider ETAcore owns exactly: identity · money · messaging — nothing else
Modular super app architecture for the Tunisia home-services platform: native customer and provider apps over independently released cleaning, repairs, and delivery modules, all on a deliberately thin shared core with one unified ledger for card and cash payments, so a new service line launches without touching the ones already live.
Approach

How the engagement ran

Delivery order matters as much as what was built. Each phase had to be safe to stop on.

  1. /001/

    Phase 1 — Core and first vertical

    Built identity, wallet, chat, and notifications, then shipped cleaning on top of them as the proving vertical. Cleaning had the highest booking volume, so it stress-tested the core first.

  2. /002/

    Phase 2 — Repairs and delivery modules

    Added the two remaining verticals as independent modules consuming the same core, deliberately without core changes beyond one wallet splitting rule, which validated the thin-core boundary.

  3. /003/

    Phase 3 — Migration and retirement

    Moved existing users from the three legacy apps with account linking, kept the old apps alive until parity was confirmed, then retired them and consolidated the store listings.

Outcomes

Results and key facts

Qualitative outcomes and engagement shape, without invented numbers.

Three apps became one

One listing, one account, one wallet. Marketing spend that had been split across three acquisition funnels now compounds on a single install.

Verticals ship independently

Each module releases on its own cadence. No vertical's launch has ever been blocked by another's release, which was the explicit failure mode the architecture was built to prevent.

Cash and card in one ledger

Providers are paid from one balance whether the customer paid cash or card, removing the reconciliation work that split payments used to create.

Engagement
Build to first release, then ongoing
Team
In-house Softwise engineers
Stack
Swift, Kotlin, Node.js, PostgreSQL
Architecture
Modular super app: shared identity, wallet, and chat core with independent service verticals
Outcome
3 apps consolidated into 1, one account and one wallet across all services
FAQs

Questions about this super app · mobile project.

The questions this project is usually asked about. Still stuck? Ask us directly.

A single mobile app offering several distinct services (for example transport, delivery, and payments) behind one account and one wallet. WeChat, Grab, and Careem are the best-known examples.

When the same customers plausibly use more than one of your services and acquisition cost is your constraint. One install and one login turn each vertical into a discovery channel for the others. If the audiences do not overlap, separate apps stay simpler.

Keep the shared core deliberately small (identity, money, messaging) and give each vertical its own module and release schedule. The moment two verticals must release together, the architecture has failed.

For this product the booking flow, live tracking, and maps are the whole experience, and those are exactly where cross-platform wrappers feel slow. The shared core and API layer already give us most code reuse; the screens themselves stayed native.

Account linking: an existing user signed in once and their history, saved addresses, and payment setup carried over. The legacy apps stayed available until each vertical's module met parity, then the old listings were retired.