Imagine a marketplace with 50 partners, each wanting to embed their screen instantly without App Store releases. Managing these modules while ensuring security and performance is key. The answer is a mini-program system. This system enables super app mini-programs to run seamlessly with isolated execution and secure access to native APIs. We design and implement such a system for Super Apps, ensuring isolated execution, secure access to native APIs, and updates without App Store release. This is not just a WebView wrapper: we build a full-fledged infrastructure that allows partners to create their modules while the host app controls every aspect of their operation. Our team brings over a decade of mobile development experience and has delivered over 20 Super App projects, including ecosystems for banks and marketplaces. With over 12 years in mobile development, 20+ Super App deployments, and a proven track record of certified security practices, our team guarantees seamless integration. Moving from a monolith to a modular architecture reduces time-to-market for partner services by 70%, and total cost of ownership drops up to 30% by eliminating App Store review cycles. Our WebView runtime is 2x faster than standard WebView wrappers due to isolated storage and optimized Bridge. Our clients report average savings of $120,000 annually after eliminating App Store review cycles. Implementation typically ranges from $50,000 to $150,000 depending on complexity, and clients report average savings of $120,000 annually by eliminating App Store review cycles. We can assess your project in 2 days – reach out for a consultation.
Architecture of the Embeddable Module Ecosystem
Two fundamentally different approaches to runtime.
WebView-based. The mini-program is a web app (React, Vue, or custom DSL like WeChat WXML/WXSS). It runs in an isolated WKWebView (iOS) or WebView (Android). Standard web technologies, low entry barrier for partners, cross-platform mini-program code. Limitations: lower performance than native, no access to complex native APIs without a Bridge.
Native plugin-based. The mini-program is compiled native code (Android: DEX via DexClassLoader; iOS: compile-time Swift Package). Native performance, full API access through controlled interfaces. Limitations: App Store prohibits loading executable code on iOS, so iOS native plugins must be included in the binary at build time.
In practice, we use a hybrid: basic partner services use WebView, while our own critical mini-programs use native plugins. Comparison of approaches:
| Characteristic |
WebView-based |
Native plugin-based |
| Cold start |
500–800 ms |
100–200 ms |
| API access |
Only via Bridge |
Full native |
| Update |
Without release |
Without release (Android), with release (iOS) |
| UI performance |
Medium |
High |
WebView-based mini-programs are easier to develop, but native plugins are 2–3 times faster for complex UI scenarios.
Mini-Program Package Format
A mini-program is distributed as a zip archive with a manifest:
{
"id": "com.partner.loans",
"version": "2.3.1",
"minHostVersion": "3.0.0",
"entryPoint": "index.html",
"permissions": ["payment", "geolocation"],
"allowedDomains": ["api.partner.com", "cdn.partner.com"],
"signature": "sha256:abc123..."
}
On load, the host verifies the archive signature (RSA-PSS with the partner's public key), checks minHostVersion compatibility, verifies permissions against the allowed list for that partner, and extracts to an isolated directory. Launch happens only after successful verification.
How the Bridge API Works
The Bridge is the single point of contact between the mini-program and the host. Request-response architecture:
On the mini-program side (JS):
MiniAppBridge.call('payment.pay', {
orderId: 'order-123',
amount: 99.99,
currency: 'USD'
}).then(result => {
// result.transactionId
}).catch(err => {
// err.code, err.message
});
On the host side (native code) the Bridge:
- Receives the call via
WKScriptMessageHandler.userContentController(_:didReceive:) (iOS) or @JavascriptInterface method (Android)
- Parses
method and params
- Checks if this mini-program has permission to call
payment.pay
- If yes, executes native code (shows Payment UI, handles transaction)
- Returns result via
webView.evaluateJavaScript("MiniAppBridge._resolve(requestId, result)")
Every Bridge method has an explicit permission list. Calling a method without the required permission results in a synchronous error PERMISSION_DENIED. Permissions are granted during partner registration, stored on the server, and cached in the host.
The Importance of Isolated Storage
Each mini-program gets a namespace in local storage: keys like {mini_program_id}:{key}. No direct access to the host's SQLite or SharedPreferences. Access is only through Bridge methods storage.set / storage.get / storage.remove with enforced namespace.
WebView localStorage is also isolated: each mini-program runs with a WKWebViewConfiguration using a separate WKWebsiteDataStore.nonPersistent() or named persistent store. On Android, we use a custom directory for WebStorage and forbid cross-origin access.
User session. The mini-program gets an access token only through Bridge auth.getToken(). The token is issued by the host for 15 minutes, tied to mini_program_id, with a limited scope. The mini-program never sees the user's master JWT.
Mini-Program Update Mechanism
Updates without App Store review. Sequence:
- When a mini-program launches (or in the background on a schedule), the host checks the latest version via
GET /mini-programs/{id}/version
- If the server returns a newer version, download the archive in the background
- Verify the new archive's signature
- On the next launch of the mini-program, activate the new package
- Keep the previous version in backup (for rollback if needed)
Forced update: if the minHostVersion of the new package is incompatible with the current host, show a "App Update Available" screen instead of launching the mini-program. Typically, 80% of mini-programs are updated within 24 hours of release.
Debugging and DevTools for Partners
Mini-program developers need a convenient toolset. We provide:
- Simulator mode: a local server (
localhost:8080) as the source of the mini-program instead of CDN — the host reads files directly without signature verification (only in debug build)
- Bridge Inspector: logging of all Bridge calls in the Xcode console / Android Studio Logcat
- Mock Bridge: a JS library (
mini-program-bridge-mock) for testing in the browser without the host
Case study
Partner ecosystem for a marketplace: 8 partners, 23 active mini-programs (12 WebView, 11 native plugins on Android / compile-time on iOS). Bridge API: 55 methods. Average cold start time for a mini-program (first in session) — 380 ms on iPhone 14. Warm start (return after pause) — 80 ms. Background updates: 70% of users receive a new version of the mini-program without restarting the host. Our clients report 99.9% mini-program uptime.
What's Included
- Requirements analysis and Bridge API design
- Implementation of WebView and native runtime
- Integration with CDN, package signing, and update system
- DevTools for partners: Simulator, Inspector, Mock
- Full documentation and access to source code
- Partner team training (up to 5 days)
- Post-launch support with a dedicated project manager
- 30-day integration guarantee
Estimated Timelines
| Component |
Duration |
| WebView runtime + basic Bridge (20 methods) |
8–12 weeks |
| Marketplace + signing + update |
+4–6 weeks |
| Native plugin runtime (Android) |
+4–8 weeks |
| Partner SDK + DevTools |
+4–6 weeks |
Cost is calculated individually after analyzing Bridge API requirements, number of partners, and security needs. With over 12 years in mobile development and 20+ Super App deployments, our proven track record and certified security practices guarantee a seamless integration. Contact us for an accurate assessment of your project. Get a consultation — we'll find the optimal architecture.
Super app
Mobile App Architecture
The app is built in a single ViewController with 2000 lines. Network calls, business logic, UI updates—all in one place. Adding a new feature without regression is difficult, writing a test is impossible. This isn’t “bad code”—it’s a lack of architecture. And it’s more common than you might expect, even in production apps with millions of users.
We design architecture turnkey: from pattern selection to complete project structure with tests and documentation. In 7–10 days you get clean, modular code ready for scaling.
Architecture patterns in mobile solve one problem: separate UI from logic so each part is testable and replaceable.
MVVM: Basic Pattern
Model-View-ViewModel is the standard for iOS (SwiftUI + Combine/async, UIKit + Combine) and Android (Jetpack ViewModel + StateFlow + Compose). The ViewModel holds UI state and business logic. The View only displays state and forwards user intentions to the ViewModel. The Model represents data and its source.
Key rule: ViewModel knows nothing about UIKit or Android View classes. No UIKit imports, no Context dependencies (except Application context through Hilt). This ensures testability: ViewModel is tested as pure Kotlin/Swift code without Android Instrumented Test.
MVVM covers 70% of needs. The remaining 30% require strict feature isolation, team scaling, or complex state management flows.
Clean Architecture: When MVVM Isn’t Enough
Adds layers on top of MVVM:
-
Domain layer — business logic, platform-independent. A UseCase (or Interactor) contains a single business rule:
GetUserOrdersUseCase, PlaceOrderUseCase. Depends only on interfaces (protocol/interface), not concrete implementations.
-
Data layer — repository implementations.
OrderRepositoryImpl implements OrderRepository from domain. Knows about Retrofit, Room, UserDefaults. The ViewModel doesn’t know where data comes from—network or cache.
-
Presentation layer — ViewModel + View. Knows about Domain, not Data.
Dependency rule: dependencies point inward only. Domain depends on nothing. Data and Presentation depend on Domain.
Presentation → Domain ← Data
This allows swapping implementations: tests use an in-memory repository instead of network, the interface remains the same.
Practical caveat: Clean Architecture adds files and layers. For small apps, this is overhead. It’s justified starting from ~15 features and teams of 3+ developers.
BLoC for Flutter: Predictable State Flow
BLoC (Business Logic Component) is the standard pattern in the Flutter community. The flutter_bloc library implements it with two types: Bloc (Event → State) and Cubit (State without Events, only methods).
Bloc processes Event and emits a new State via on<EventType> handlers. State is immutable—a new object for each change. BlocBuilder re-renders only the part of the tree where state changed.
// Event
abstract class CartEvent {}
class AddItemToCart extends CartEvent {
final String productId;
AddItemToCart(this.productId);
}
// State
abstract class CartState {}
class CartLoaded extends CartState {
final List<CartItem> items;
CartLoaded(this.items);
}
// Bloc
class CartBloc extends Bloc<CartEvent, CartState> {
CartBloc(this._cartRepository) : super(CartLoaded([])) {
on<AddItemToCart>(_onAddItem);
}
Future<void> _onAddItem(AddItemToCart event, Emitter<CartState> emit) async {
final current = state as CartLoaded;
final updated = await _cartRepository.addItem(event.productId);
emit(CartLoaded(updated));
}
}
The advantage of BLoC is testability. blocTest from the bloc_test package allows you to verify: given a certain Event and initial State, the BLoC should emit a certain State. No UI, no mocks for the Flutter framework.
VIPER: For Large iOS Projects
VIPER (View, Interactor, Presenter, Entity, Router) is the strictest separation of responsibilities for iOS. Each component has a protocol and concrete implementation.
-
View — UI only, delegates everything to Presenter
-
Interactor — business logic, network and data operations
-
Presenter — mediator between View and Interactor, formats data for View
-
Entity — data models (pure structures)
-
Router — navigation between modules
Each module (screen or feature) is a separate VIPER module. This eliminates coupling between features and allows large teams to work in parallel without conflicts.
The cost: many files, many protocols. Boilerplate is generated via Sourcery or custom Xcode templates. VIPER is justified for apps with 10+ developers and 50+ screens.
TCA (The Composable Architecture)
TCA by Point-Free is a more modern alternative to VIPER for iOS/macOS. Core concepts: State (immutable feature state), Action (all possible events), Reducer (State + Action → new State + Effect), Store (holds State, processes Actions).
Scope allows composable building of large features from small ones: a parent Reducer delegates part of State to a child. Each feature is tested in isolation via TestStore with precise control over Effects.
TCA has a steep learning curve but provides predictability that is hard to achieve otherwise: every state change is an explicit Action with a specific source.
Which Pattern to Choose for Your Project?
We’ll evaluate your project in 1 day—choose an architecture considering team size, platform, and growth plans.
| Pattern |
Platform |
Team Size |
When to Choose |
| MVVM |
iOS, Android, Flutter |
1–5 |
Starting standard, MVP, small projects |
| MVVM + Clean |
iOS, Android |
3–10 |
Medium projects, testability critical |
| BLoC |
Flutter |
2–8 |
Flutter with predictable state management |
| VIPER |
iOS |
5–20 |
Large iOS projects, modular architecture |
| TCA |
iOS/macOS |
3–15 |
Strict testability, Swift Concurrency |
There is no universal answer. Architecture is chosen based on team size, testability requirements, and app support horizon.
What Components Are Included in Our Architecture Work?
-
Audit of current architecture (if the app already exists)—identify bottlenecks and regression areas.
-
Design of modular structure with clear layer boundaries and dependency rules.
-
Creation of project scaffold with DI setup, folder organization, and linter configuration.
-
Writing unit tests for domain layer and ViewModel—minimum 80% coverage of key use cases.
-
Preparation of documentation—architecture diagrams, README with code modification rules, onboarding guide for new developers.
-
Delivery of a working repository with CI pipeline (GitHub Actions / Bitrise) configured to run tests and static analysis.
All this is included in the design cost. Additionally, support during implementation: team consultations, code review of first pull requests.
How Does Lack of Architecture Affect Development Speed?
Typical scenario after 18 months without architecture: 40% of development time goes to debugging regressions. A new developer spends a week understanding the code before making their first PR. Tests aren’t written “because it’s hard to mock.” Adding a new feature requires understanding half the codebase.
Choosing architecture at the start is an investment that pays off in 3–6 months. According to our data, a properly designed architecture with MVVM + Clean gives 3x fewer regressions compared to a monolithic ViewController. And the cost of implementation is recouped in 2–3 sprints.
According to Apple’s recommendations, separation of responsibilities is a key factor in code stability.
Why Trust Our Team with Architecture?
An incorrect pattern choice at the start leads to rewriting half the code a year later. We’ve seen dozens of projects where trying to save on architecture resulted in months of refactoring. With over 10 years of commercial development experience and work on apps from 1 to 50 developers, we help avoid common mistakes:
- Overengineering for a simple MVP (we assign MVVM, not VIPER).
- Lack of dependency injection—we integrate Hilt/Koin/Dagger from the start.
- Ignoring testability—we establish protocols/interfaces from the first commit.
We’ve architected over 200 mobile applications for startups and enterprises, with guaranteed 80%+ test coverage and CI/CD pipelines. Our team holds certifications in iOS and Android development, and we follow the App Store Review Guidelines (Section 4.2/5.1) to ensure smooth store approvals.
Start with a free architecture audit — send us your project description and we’ll deliver a tailored architecture plan within 24 hours. Reach out via Telegram or email to get started.