Skip to Content
v0.8.0 · shippedNative iOS / Android / Flutter / Capacitor SDKs, A2A discovery, SOC 2 readiness, residency, BYO storage, BYOK. Read the changelog →
Migration guidesNative iOS / Android → Hybrid

Native iOS / Android → Hybrid

Weeks High risk

When (and how) to wrap an existing pure-native iOS / Android app with Capacitor or React Native, keeping the platform Mushi SDKs in place.

This is a strategic guide more than a tactical one — most apps that get this far DON’T need to migrate. Read the “Should you migrate” section first.

Should you migrate?

Migrate if two or more of these are true:

  • ☐ You’re shipping the same feature twice in Swift and Kotlin and the parity work is eating > 30 % of your engineering time.
  • ☐ You have an existing web app whose UI you’d like to share with mobile.
  • ☐ Your app’s core surface is forms / lists / chat / dashboards (high JS affinity); not games, AR, video editors, or audio DSP.
  • ☐ You’re losing native engineers and can hire React engineers more easily.

DON’T migrate if:

  • Your app’s value is performance-bound native (camera, GL, audio, VPN).
  • Your team is happy and ships steadily on native.
  • You can’t afford a 6–12 month parallel-track migration.

If you proceed, the realistic outcome is hybrid — most of your screens in JS, a handful of performance-critical surfaces left in Swift / Kotlin, bridged to JS via TurboModules (RN) or Capacitor plugins.

Pick a target shell

CapacitorReact Native
Reuse web codebaseYes (it IS the web app, in a WebView)Mostly — RN uses React but not DOM components
Native fidelityWebView ceiling~Native, with effort
Migration sizeSmaller (you can wrap a static export)Larger (every screen is rewritten)
Team profileWeb devs onlyReact devs + some native fluency
Mushi support@mushi-mushi/capacitor + @mushi-mushi/web for the WebView@mushi-mushi/react-native

Pick Capacitor if you already have a strong web product and just need a native shell. Pick React Native if you want to ship native UX from JS and you don’t have a meaningful web app.

Migration checklist

Migration checklist
8 required steps
  1. Step 01
    Audit native surfaces — what stays native?
  2. Step 02
    Run a 2-week spike on the most complex screen
  3. Step 03
    Pick the shell — Capacitor or React Native
  4. Step 04
    Port the design system
  5. Step 05
    Pilot one user-facing flow end-to-end
  6. Step 06
    Wire Mushi: keep the native SDK AND add the JS one
  7. Step 07
    Roll out screen-by-screen behind a feature flag
  8. Step 08
    Sunset native screens once their hybrid versions are stable

Mushi during the migration

You’ll have two Mushi SDKs running side by side for the migration window:

Both must use the same projectId and apiKey. Reports from each land in the same inbox; the SDK tag on the report (ios, android, capacitor, react-native) lets you tell them apart on the dashboard.

// Native iOS — stays as-is during the migration import Mushi from "MushiMushi" Mushi.shared.configure(projectId: "YOUR_PROJECT_ID", apiKey: "YOUR_PUBLIC_KEY")
// JS shell — added on top import { Mushi } from '@mushi-mushi/capacitor' await Mushi.configure({ projectId: 'YOUR_PROJECT_ID', apiKey: 'YOUR_PUBLIC_KEY' })

When the migration completes and you remove the native shell entirely, you also remove the native Mushi SDK; the JS one carries on alone.

Verification

  • Both SDKs land reports under the same project.
  • The dashboard SDK-tag filter shows reports from both surfaces during the migration window.
  • Crash rate on the hybrid surfaces ≤ 1.2 × the native surface’s rate (perfect parity is unrealistic in week 1; should approach 1.0 × within 4 weeks).

References

Last updated on