White-Label Mobile Applications: SDK, Modular Architecture and Multi-Tenancy
White-label — not just "rebrand the application". This is an architectural decision needed from start. Trying to make white-label from monolithic application retroactively — one of most expensive refactorings in mobile development.
What Means "Proper" Modular Architecture for White-Label
Key principle: no business logic module should know about specific client. Configuration, colors, texts, feature flags — everything comes from outside via dependency injection, not hardcoded.
On iOS proper structure: Swift Packages for each domain (AuthKit, PaymentsKit, ProfileKit), separate AppKit for entry point, and BrandKit — package with specific client theme. Main application — thin wrapper assembling them together.
// Wrong
class PaymentViewController: UIViewController {
let primaryColor = UIColor(hex: "#FF5722") // hardcoded client A
}
// Correct
class PaymentViewController: UIViewController {
let theme: AppTheme // injected on build
}
On Android equivalent — Gradle multi-module with productFlavors. Each flavor builds application for specific client: substitutes google-services.json, theme, resources. One repository, multiple artifacts.
Theming: Beyond Colors and Fonts
Surface-level white-label — change colors and logo. Takes a day. Real customization — when client can disable module, change onboarding screen order, use their payment provider.
In React Native for deep theming: ThemeProvider (React Context) at top level, design tokens (colors.primary, spacing.md) via theme object, components get values only through tokens. For Flutter: ThemeData + ThemeExtension for custom tokens beyond Material Design.
Runtime theming (loading theme from server) — separate complexity level. On iOS requires UIAppearance proxy + manual update for existing views; SwiftUI with Environment and @EnvironmentObject for theme simplifies significantly.
Multi-Tenant: One Backend, Different Applications
If multiple white-label applications use common backend, tenant identification needed at API level. Option 1: X-Tenant-ID header in each request. Option 2: separate subdomains (clienta.api.example.com). Option 3: tenant from JWT token after authentication.
At mobile app level: tenant ID either hardcoded in build configuration (via xcconfig / gradle.properties), or determined dynamically (by bundle ID or via Remote Config). Dynamic determination needed if one binary serves multiple clients — rare but real case for enterprise.
SDK: When White-Label is a Library
If product embeds in third-party applications — this is SDK, not white-label app. Requirements fundamentally different.
iOS SDK via Swift Package Manager: Package.swift describes product, target, dependencies. Published via git tag. Critical: don't pull transitive dependencies unnecessarily — each SDK dependency potentially conflicts with host app dependencies.
Android SDK via Maven (Artifactory or GitHub Packages): AAR artifact with POM metadata. api() vs implementation() in gradle — only what client needs, expose in api(). Everything internal — implementation().
SDK versioning via Semantic Versioning — mandatory. Breaking changes in minor version — death for B2B product.
Multi-Brand Build Automation
For 5+ white-label clients manual building is irrational. Fastlane with lanes per client and shared methods — basic option. More mature: parameterized CI pipeline where pass CLIENT_ID and get built IPA/APK/AAB for specific brand.
Codemagic supports environment variables per workflow — convenient for multi-brand builds without complex Fastfile.
Timeline: refactoring monolith to multi-tenant architecture — 2-3 months. New white-label application with proper architecture from scratch — 3-4 months. Developing mobile SDK — from 6 weeks for simple, from 3 months for full-featured.







