Mini-Program Inter-Process Communication with Host Application
A mini-program lives in an isolated context — its own WebView, its own memory, potentially its own process. But users expect it to see wallet balance in the Super App, initiate a taxi order from another mini-program, receive push notifications through a shared host channel. This is inter-process communication (IPC). And here, architectural decisions have direct security consequences for the entire platform.
The Problem: Why Standard Bridge Isn't Enough
The JS Bridge described in the container context solves "mini-program → host native API." But IPC covers different scenarios:
- Mini-program → host application data: read user profile, balance, order history
- Host → mini-program: send events (balance changed, order arrived, session state changed)
-
Mini-program A → mini-program B: pass parameters on open, return result on close (like
startActivityForResulton Android) - Mini-program → host background service: start long-running operation (file upload, background tracking)
First mistake: implement everything through one synchronous bridge method getData(key). This creates a data store inside the container that any mini-program can potentially access. Without strict permission model, any mini-app reads any other's data.
Architecture: Event Bus Over Bridge
The correct approach is a typed event system with namespace isolation:
// In mini-program SDK
sdk.host.subscribe('wallet.balanceChanged', (payload) => {
updateUI(payload.balance)
})
sdk.host.emit('order.created', { items, total })
On the native side this is NotificationCenter (iOS) or LocalBroadcastManager / EventBus (Android) with a proxy layer that:
- Receives emit from a specific mini-program
- Checks that the mini-program has permission for this event namespace
- Routes the event — either within host or to another mini-program
Routing between mini-programs requires separate solutions. If they're in different processes, real IPC is needed. On Android this is Messenger + IBinder via AIDL, or simpler cases use ContentProvider as a shared data bus. On iOS between WKWebView processes — only through host as mediator (Darwin notifications or XPC if WKWebView runs in a separate Extension).
Request-Response Pattern for Mini-Program to Mini-Program
Scenario: maps mini-program wants to open navigation mini-program and get back the selected route.
On Android this is like startActivityForResult, implemented through container:
// In maps mini-program
const route = await sdk.miniapp.open('com.maps.navigation', {
origin: currentLocation,
destination: selectedPoint
})
// route received when navigation mini-program calls sdk.miniapp.finish({route})
Container stores the call's correlation ID, launches target mini-program with parameters via deep link format (miniapp://com.maps.navigation?callId=uuid¶ms=base64), and when it calls finish() — delivers result to caller's promise.
Timeout on awaiting result is mandatory. User can simply close the navigation mini-program without selecting a route. Container must resolve the promise with {cancelled: true} within 0 ms on close.
Host Data: Scoped Data Access
The most sensitive part of IPC is mini-programs' access to host application data. User profile, payment data, history.
Implement through Data Provider API with explicit scopes:
// Mini-program requests only what it declared in manifest
const user = await sdk.host.getUser(['name', 'phone', 'avatarUrl'])
// email and paymentMethods — unavailable without corresponding scope in manifest
On native side — Provider Registry: dictionary {scope → handler}. Each handler knows which mini-programs it's open to (can restrict with bundle ID whitelist). Data serializes to JSON, passes through bridge. Sensitive fields (tokens, full card numbers) — never. Only tokenized representations.
Push Events from Host to Active Mini-Program
Host received a WebSocket message about a new order. Courier mini-program is open. Need to notify without user action.
On iOS: webView.evaluateJavaScript("window.__miniapp_dispatch__('\(eventJSON)')"). Safe only when WebView is stable (after webView:didFinishNavigation:). Until then — queue pending events, drained after load complete.
On Android similarly via webView.evaluateJavascript(), but check WebView isn't in PAUSED state (JS won't execute otherwise).
For background mini-programs — events go to persistent queue and deliver on next foreground. Critical events (session token expired) — sent to host's system notification channel, visible to user regardless of mini-program state.
Isolation: What Mini-Programs Must NOT See
Inter-process channels easily become attack vectors. Minimal restrictions:
- Mini-program doesn't know the list of other installed mini-programs (fingerprinting)
- Direct mini-program → mini-program communication only through host container, never directly
- Event payloads logged (without sensitive data) for audit
- Rate limiting on emit: no more than 100 events per second from one mini-program
Timeline for implementing IPC subsystem within existing Super App with ready container: 6 to 14 weeks depending on scenario scope and security requirements. Full Event Bus + Scoped Data Access + Request-Response closer to upper bound.







