Skip to content
Published on

クロスプラットフォーム・モバイル開発 2026 徹底ガイド — React Native・Flutter・Expo・Capacitor・Tauri 2・Kotlin Multiplatform・Compose MP・.NET MAUI・NativeScript・Lynx

Authors

プロローグ — 2026年、「一度書いて両方動かす」という約束の新しい局面

2015年に React Native が初めて登場したとき、「一度書いて iOS と Android の両方で動かす」という約束は巨大だった。Facebook が自ら作り、JSX で書き、JavaScript ブリッジ経由でネイティブビューを操作する。それは約束であると同時に限界でもあった。ブリッジは非同期で、シリアライゼーションのコストが大きく、滑らかな 60fps を維持することは常に戦いだった。

2026年5月、風景は変わった。

  • React Native 0.76 (Meta、2024年10月リリース、2026年現在の運用期) の New Architecture (Fabric レンダラー + TurboModules + JSI) が新規アプリのデフォルトになった。ブリッジのシリアライゼーションは消え、同期的なネイティブ呼び出しが可能になった。
  • Flutter 3.27 (Google、2024年末リリース、2026年運用期) は Impeller レンダラーを iOS と Android 両方のデフォルトにした。動的な Skia シェーダーコンパイルは消え、事前コンパイル済みシェーダーで初回フレームのカクつき (jank) はほぼなくなった。
  • Tauri 2.0 (Tauri チーム、2024年10月) が iOS と Android のモバイルターゲットを正式サポートし始めた。「Rust でモバイル」が初めて現実的になった。
  • JetBrains Kotlin Multiplatform 2.1 と Compose Multiplatform 1.7 は iOS の共有 UI を安定段階へ押し上げた。
  • ByteDance Lynx が 2025年3月にオープンソース化された。TikTok / 抖音のライブコマース UI やミニアプリを動かしていた社内フレームワークが外部に出た事件だ。

クロスプラットフォームに単一の正解はもはやない。この記事は 2026 年のモバイル・クロスプラットフォーム・スタックを一息で整理する。


1章 · クロスプラットフォームが解く本質的な問題

iOS は Swift / Objective-C と UIKit / SwiftUI、Android は Kotlin / Java と Views / Jetpack Compose を使う。両プラットフォームは言語・UI ツールキット・ツールチェイン・配布チャネルすべてが異なる。「ビジネスロジックと画面を一度だけ書いて両方で動かしたい」という欲求が根強く残るのはこのためだ。

クロスプラットフォームはこの問題を 5 つの異なる戦略で解く。

  • JavaScript ブリッジ (従来の React Native): JS コードがネイティブビューをリモート制御する。
  • JSI 直接呼び出し (現代の React Native、New Architecture): JS とネイティブが同じメモリと同期呼び出しを共有する。
  • 自前レンダラー (Flutter、Lynx): プラットフォームビューを使わずキャンバスに直接描く。
  • WebView (Capacitor、Ionic、Cordova): ウェブ UI をネイティブコンテナに載せる。
  • ビジネスロジック共有 (Kotlin Multiplatform、KMP): ビジネスコードは共有、UI は完全ネイティブ。

選択はドメインに依存する。ゲームは自前レンダラーを好み、社内ツールは WebView で十分、メッセンジャーや EC は New Architecture RN か KMP のどちらかに収束する傾向がある。


2章 · React Native New Architecture — JSI・Fabric・TurboModules

React Native 0.76 で安定化された New Architecture は 3 つの部品からなる。

  • JSI (JavaScript Interface): V8 / Hermes と C++ の間の薄いインターフェース。JS オブジェクトが C++ の HostObject として直接公開され、シリアライゼーションなしで呼び出せる。
  • Fabric: 新しいレンダラー。JS が React ツリーを構築し、それが C++ の Shadow Tree に変換され、メインスレッドで直接ネイティブビューにコミットされる。同期レイアウトが可能になる。
  • TurboModules: ネイティブモジュールを JSI ベースで書き直したもの。モジュールは遅延初期化され、呼び出しは同期・非同期どちらでも可能。

従来の RN ではすべての呼び出しが「シリアライズ → JSON → ネイティブのデシリアライズ → 非同期コールバック」だったが、New Architecture では JS が C++ ポインタを直接持って関数を呼ぶ。ホットリロードは依然高速で、デバッグも引き続き React DevTools。

// TurboModule 定義: spec/NativeMathModule.ts
import type { TurboModule } from 'react-native'
import { TurboModuleRegistry } from 'react-native'

export interface Spec extends TurboModule {
  add(a: number, b: number): number
  factorial(n: number): Promise<number>
  getDeviceLocale(): string
}

export default TurboModuleRegistry.getEnforcing<Spec>('NativeMathModule')
// 利用: App.tsx
import NativeMathModule from './spec/NativeMathModule'

export default function App() {
  // 同期呼び出し — ブリッジなしで直接ネイティブ関数を呼ぶ
  const sum = NativeMathModule.add(2, 3)
  const locale = NativeMathModule.getDeviceLocale()
  return null
}

codegen ステップが Spec インターフェースを読み、iOS の Objective-C++ ヘッダーと Android の Java / Kotlin インターフェースを自動生成する。型安全性は旧 NativeModules よりも飛躍的に良くなった。


3章 · Hermes — JavaScriptCore から自前エンジンへ

Hermes は Meta がモバイル RN のために作った JS エンジンだ。2026 年現在、RN のデフォルトエンジンになっている。

  • バイトコードを事前コンパイル (AOT) するため起動時間が短い。
  • ガベージコレクタはモバイル向けにチューニングされている (短い stop-the-world)。
  • メモリフットプリントは V8 より小さい。
  • ES2015+ の大部分をサポートし、Proxy や正規表現の一部に制約がある。

歴史的に iOS RN は JavaScriptCore (JSC) を使い、Android は V8 か JSC を使っていた。Hermes は両プラットフォームで同一の挙動を保証しつつ、起動時間をほぼ半分にした。<200ms cold start が可能になる理由だ。


4章 · Flutter — Skia から Impeller へ

Flutter は最初から自前のレンダラーを持つフレームワークだった。プラットフォームの UIKit や View を使わず、Skia で直接ピクセルを描く。2026 年の変化はレンダリングエンジンが Skia から Impeller に移ったことだ。

  • Skia: Chromium の 2D グラフィックスエンジン。Flutter 初期から使われている。強みは互換性と成熟度。弱みはランタイムのシェーダーコンパイルによる初回フレームのカクつき。
  • Impeller: Flutter チームが自前で開発したレンダラー。シェーダーをビルド時に事前コンパイルし、Metal (iOS) と Vulkan (Android) を直接使う。初回フレームの jank はほぼ消えた。

Flutter 3.27 以降、iOS / Android ともに Impeller がデフォルトだ。一部の複雑なシェーダー効果は Skia フォールバックを使うが、一般的なアプリの 99% は Impeller で滑らかに動く。

// Flutter: 標準的な Material アプリ
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '2026 Cross-Platform Demo',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});
  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _count = 0;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter')),
      body: Center(child: Text('Count: $_count', style: const TextStyle(fontSize: 32))),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() => _count++),
        child: const Icon(Icons.add),
      ),
    );
  }
}

Dart は AOT コンパイルでネイティブのマシンコードに変換されるため、JIT のウォームアップがない。起動は速く、60fps の維持も比較的容易だ。欠点はバイナリサイズが大きいこと — 標準的な Flutter アプリは iOS で約 15MB、Android で 8-10MB を占める。


5章 · Expo — RN 開発体験の事実上の標準

Expo は最初「RN を始めやすくする道具」だったが、2026 年には React Native の事実上の標準開発環境になった。Expo SDK 53 (2026 年上半期) の主要コンポーネント:

  • EAS Build: クラウドビルドサービス。iOS は Mac が必要だが、EAS がクラウドで処理する。
  • EAS Submit: App Store / Play Store への自動提出。
  • EAS Update: OTA (Over-the-air) 更新。ネイティブを変えない JS の更新をプッシュ配信。
  • Expo Router: ファイルベースルーティング。Next.js 風の app/ ディレクトリ構造を RN に持ち込む。
  • Expo Atlas: バンドル解析ツール。どのモジュールがバンドルサイズを占めるかを可視化。
  • Expo Modules: TurboModule の作成を簡単にするラッパー。Swift / Kotlin でモジュールを書くと JS バインディングが自動生成される。
# Expo SDK 53 の新規アプリ
npx create-expo-app@latest my-app --template default

cd my-app

# ローカル開発
npx expo start

# クラウドビルド
npx eas build --platform ios --profile development
npx eas build --platform android --profile production

# OTA アップデートを配信
npx eas update --branch production --message "fix: button text typo"

Expo Router は RN のルーティングを根本的に変えた。

# ファイル構造
app/
  _layout.tsx       # ルートレイアウト (タブまたはスタック)
  index.tsx         # ホーム (/)
  login.tsx         # ログイン (/login)
  (tabs)/
    _layout.tsx     # タブレイアウト
    index.tsx       # タブホーム
    profile.tsx     # タブのプロフィール (/profile)
  product/
    [id].tsx        # 動的ルート (/product/123)

React Navigation を手書きしていた旧 RN パターンと比べると、Expo Router は Next.js 出身の開発者にとって学習コストがほぼゼロだ。


6章 · Capacitor 7 + Ionic — WebView 陣営の進化

Capacitor は Ionic チームが作った WebView ベースのクロスプラットフォーム・ランタイムだ。Cordova の後継であり、2025 年の Capacitor 7 は意義のある進化を遂げた。

  • ウェブ UI (React、Vue、Angular、Svelte 自由選択) をネイティブコンテナに載せる。
  • ネイティブ機能 (カメラ、GPS、プッシュ、ファイル) はプラグインシステムでアクセス。
  • 100% ネイティブのビルド成果物 (.ipa、.apk)。
  • PWA をそのままモバイルアプリへ移植できる。
// Capacitor: カメラプラグインの利用
import { Camera, CameraResultType } from '@capacitor/camera'

async function takePhoto() {
  const photo = await Camera.getPhoto({
    quality: 90,
    allowEditing: false,
    resultType: CameraResultType.Uri,
  })
  // photo.webPath は img 要素の src にそのまま使える
  return photo.webPath
}

Capacitor 7 の主要な変化: iOS WKWebView と Android WebView の双方が最新エンジンに統一された。結果として、モダン CSS (Container Queries、View Transitions API) や WebGPU の一部機能が動作する。

Capacitor が合うとき: コンテンツ中心のアプリ、社内ツール、市場投入速度を優先する MVP、既存のウェブチームコードの再利用。合わないとき: 重いアニメーション、ゲーム、60fps スクロールが必須のフィード。


7章 · Tauri 2 Mobile — Rust でモバイル

2024 年 10 月の Tauri 2.0 は最大級の出来事のひとつだ。Tauri はそれまでデスクトップ専用 (Rust バックエンド + WebView フロント) だったが、2.0 から iOS と Android のモバイルを正式サポートする。

  • バックエンドは Rust で書く。iOS は静的ライブラリとして、Android は JNI 経由でビルドされる。
  • フロントはシステム WebView (WKWebView、Android WebView)。ウェブ技術 (React / Vue / Svelte) は自由。
  • IPC (Inter-Process Communication) はコマンドとイベントで標準化されている。
  • バイナリサイズは React Native / Flutter より小さい (<10MB 可能)。
# Tauri 2 モバイルプロジェクト初期化
npm create tauri-app@latest my-mobile-app
cd my-mobile-app

# Android ターゲット追加
npm run tauri android init
npm run tauri android dev

# iOS ターゲット追加
npm run tauri ios init
npm run tauri ios dev
# tauri.conf.json (要約)
app:
  product-name: my-mobile-app
  identifier: com.example.app
  windows:
    - title: my-mobile-app
      width: 800
      height: 600
bundle:
  active: true
  targets: all
  android:
    minSdkVersion: 24
  iOS:
    minimumSystemVersion: '14.0'

Tauri 2 Mobile はまだ RN / Flutter ほど成熟していない。ホットリロードはあるがプラグインのエコシステムはずっと小さく、App Store 審査の知見も浅い。それでも「Rust バックエンド + ウェブフロント + 非常に小さなバイナリ」という組み合わせはシステムプログラマにとって魅力的だ。


8章 · Kotlin Multiplatform — ビジネスロジック共有の王道

JetBrains の Kotlin Multiplatform (KMP、旧 KMM) は別の道を行く。UI は各プラットフォームのネイティブ (iOS は SwiftUI、Android は Compose) で、ビジネスロジックとデータレイヤだけを共有する

  • commonMain: 共有コード (Kotlin)。
  • androidMain: Android 専用。
  • iosMain: iOS 専用。Kotlin/Native で iOS フレームワーク (.framework) としてビルドされ、Swift からインポートする。
  • expect / actual キーワードでプラットフォーム別実装を分岐する。
// shared/src/commonMain/kotlin/Repository.kt
class UserRepository(private val api: UserApi) {
    suspend fun fetchUser(id: String): User = api.getUser(id)
}

expect class PlatformLogger() {
    fun log(message: String)
}
// shared/src/androidMain/kotlin/PlatformLogger.android.kt
actual class PlatformLogger actual constructor() {
    actual fun log(message: String) {
        android.util.Log.d("KMP", message)
    }
}
// iosApp/iosApp/ContentView.swift
import shared

struct ContentView: View {
    let repo = UserRepository(api: UserApi())

    var body: some View {
        Text("Hello, KMP!")
            .task {
                let user = try? await repo.fetchUser(id: "1")
            }
    }
}

KMP の大きな強み: ネイティブ UI をそのまま使う。 iOS は SwiftUI、Android は Compose で、両方のデザインガイドを完璧に守る。欠点は UI を 2 回書く必要があること。

トス・当根 (Karrot)・LINE・メルカリが部分的に KMP を採用し、2025〜2026 年にはカカオと楽天が検討を始めたと発表があった。


9章 · Compose Multiplatform — KMP を共有 UI まで拡張

JetBrains は KMP の限界 (UI を別々に書く必要) を解決するために Compose Multiplatform を作った。Android の Jetpack Compose を iOS・デスクトップ・ウェブにも持ち込む。

  • 同じ @Composable 関数が Android・iOS・デスクトップ・ウェブで動く。
  • iOS は Kotlin/Native と Skia ベースのレンダラーで動く (Flutter と類似)。
  • Android はそのまま Jetpack Compose で、Material 3 デザインシステムと互換。

Compose Multiplatform 1.7 (2025 年リリース) から iOS が安定 (stable) に到達した。JetBrains のデモやカカオ・トスの PoC 結果から、60fps は一般的に達成可能。

// shared/src/commonMain/kotlin/App.kt
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun App() {
    var count by remember { mutableStateOf(0) }

    MaterialTheme {
        Column(modifier = Modifier.padding(16.dp)) {
            Text("Compose Multiplatform on iOS/Android")
            Button(onClick = { count++ }) {
                Text("Clicked $count times")
            }
        }
    }
}

長所: 本当に一度だけ書く。短所: iOS ネイティブのルック&フィールに正確に合わせるには追加作業が必要。Flutter に似ているが、Kotlin である点が差別化要素。


10章 · .NET MAUI — Xamarin の後継

Microsoft の .NET MAUI (Multi-platform App UI) は Xamarin.Forms の後継だ。.NET 9 ベースで、iOS・Android・macOS・Windows をすべてターゲットにする。

  • 単一プロジェクトで複数プラットフォーム。
  • UI は C# と XAML で書く。
  • 旧 Xamarin Native (Xamarin.iOS、Xamarin.Android) は 2024 年 5 月に EOL。
  • Hot Reload、.NET MAUI Blazor ハイブリッド (WebView + .NET) もサポート。
# .NET MAUI 新規プロジェクト
dotnet new maui -n MyApp
cd MyApp

# iOS ビルド (macOS 上で)
dotnet build -t:Run -f net9.0-ios

# Android ビルド
dotnet build -t:Run -f net9.0-android

.NET MAUI はエンタープライズの .NET チームがモバイルに進出するときの自然な選択だ。日本の SI 市場にシェアがあり、韓国の一部金融機関でも採用例がある。欠点はモバイルコミュニティの規模が RN / Flutter より小さいこと。


11章 · NativeScript — Vue・Angular とともに

NativeScript は Cordova / Capacitor と RN の中間に位置する。WebView を使わないが、JS でネイティブビューを直接操作する。RN が JSI に向かう間、NativeScript は独自の V8 統合で同様の道を進んだ。

  • Vue・Angular・Svelte との統合が良好 (特に Vue / Angular チームに人気)。
  • iOS は Objective-C++、Android は Java をメタデータとして公開し、JS から直接呼び出す。
  • 旧 NativeScript Core はメンテナンスモード、@nativescript/core 8.x が現行。
  • コミュニティの規模は RN / Flutter より小さいが、Vue 基盤のモバイル開発では有効な選択肢。

NativeScript は 2026 年時点でニッチなポジションだが、Vue / Angular のコードベースをモバイルに持っていくときに学習コストが最も低いという強みがある。


12章 · ByteDance Lynx — 2025 年の新しい顔

2025 年 3 月、ByteDance は社内フレームワーク Lynx をオープンソース化した。TikTok / 抖音のライブコマース UI、ミニアプリコンテナ、コメント画面などが Lynx で動いている。

Lynx の設計哲学:

  • レンダリングエンジンの分離: JS スレッドとレンダリングスレッドを分離。JS が詰まっても UI は 60fps を維持する。
  • CSS-in-Style: React Native の StyleSheet より本物の CSS に近い文法。Flexbox・Grid・アニメーションをフルサポート。
  • マルチスレッディング: JS コードがメインスレッドを止めないよう最初から設計。
  • Web と互換: 同じコードが React DOM と Lynx の双方で動くよう抽象化。
// Lynx コンポーネント (TypeScript + JSX)
import { Component } from '@lynx-js/react'

class Counter extends Component {
  state = { count: 0 }

  render() {
    return (
      <view className="container">
        <text className="title">Lynx Counter</text>
        <text className="count">Count: {this.state.count}</text>
        <view bindtap={() => this.setState({ count: this.state.count + 1 })}>
          <text>Tap to increment</text>
        </view>
      </view>
    )
  }
}

Lynx は 2026 年時点で RN / Flutter ほど成熟していないが、ByteDance という巨大ユーザ + オープンソースという点が魅力だ。韓国・日本ではまだ採用例が少ないが、ライブコマースを運営する企業が関心を寄せている。


13章 · レンダリングモデル比較

フレームワークレンダリング方式グラフィックス API初回フレーム jank60fps の難易度
React Native (New Arch)ネイティブビュー + FabricUIKit / Android Views
Flutter (Impeller)自前レンダラーMetal / Vulkan非常に低
CapacitorWebViewWebKit / Blink
Tauri 2 MobileWebViewWebKit / Blink
Compose MultiplatformSkiaMetal / OpenGL
.NET MAUIネイティブビューUIKit / Android Views
NativeScriptネイティブビューUIKit / Android Views
Lynx自前レンダラー + スレッド分離Metal / OpenGL
KMP (UI 別)100% ネイティブUIKit / Compose最低最易

自前レンダラー陣営 (Flutter、Lynx、Compose MP) は 60fps 維持が最も容易。WebView 陣営 (Capacitor、Tauri) はコンテンツ中心アプリに適する。ネイティブビュー陣営 (RN、MAUI、NativeScript) は OS の UI ガイドに最もよく従う。


14章 · バンドルサイズ / バイナリサイズ比較

同じ「Hello World + カウンター + ネットワークリクエスト」アプリをビルドしたときのおおよそのサイズ (2026 年、iOS Release ビルド):

フレームワークiOS .ipaAndroid .apk備考
React Native (Hermes)~10MB~7MBHermes バイトコードを含む
Flutter (Impeller、AOT)~15MB~9MBDart ランタイム + アイコンフォント
Capacitor~5MB~3MBWebView 自体は OS 提供
Tauri 2 Mobile~4MB~3MBRust 静的リンク
KMP (ネイティブ UI)~3MB~2MBネイティブが基本
Compose Multiplatform~12MB~5MBiOS は Skia を含む
.NET MAUI~25MB~15MB.NET ランタイムが大きい
NativeScript~10MB~8MBJS エンジンを含む
Lynx~8MB~6MB自前レンダラー

KMP (ネイティブ UI) と Capacitor / Tauri (WebView) が最も小さい。.NET MAUI が最も大きい。


15章 · ネイティブモジュール・ブリッジ — どうやってネイティブにアクセスするか

各フレームワークがネイティブ機能にアクセスする方法。

フレームワークメカニズム実装言語型安全性
React Native (TurboModules)JSI HostObjectObj-C++ / Java / Kotlin / Swiftcodegen による強
FlutterPlatform Channels (MethodChannel)Swift / Kotlinシリアライゼーションベース、手動
CapacitorCapacitor PluginSwift / Javaデコレータベース、中
Tauri 2Command と IPCRustSerde ベースで強
KMP / Compose MPexpect / actualKotlin / Swift interopKotlin の型そのまま
.NET MAUIDependencyService / HandlerC#C# の型そのまま
NativeScriptメタデータ + リフレクションJS + Obj-C / Java メタデータランタイム
LynxNative ModuleSwift / KotlinTypeScript codegen
// React Native TurboModule (iOS) — Swift 側
@objc(NativeMathModule)
class NativeMathModule: NSObject {
  @objc func add(_ a: Double, b: Double) -> NSNumber {
    return NSNumber(value: a + b)
  }
}
// Flutter MethodChannel (Android Kotlin)
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.math"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                if (call.method == "add") {
                    val a = call.argument<Int>("a") ?: 0
                    val b = call.argument<Int>("b") ?: 0
                    result.success(a + b)
                } else {
                    result.notImplemented()
                }
            }
    }
}

型安全性は TurboModules と Tauri Commands が最も強く、NativeScript が最も弱い (ランタイムメタデータに依存)。


16章 · ホットリロード・開発体験

フレームワークHot ReloadHot RestartDevToolsデバッガ
React NativeFast RefreshありReact DevToolsChrome / Flipper / Reactotron
Flutter非常に高速ありFlutter DevToolsDart DevTools
Capacitorウェブと同じありブラウザ DevToolsChrome / Safari
Tauri 2 Mobile高速ありWeb + Rust 両方Web DevTools + lldb
KMP通常の IDEありAndroid Studio / Xcode両方のデバッガ
Compose Multiplatform高速ありCompose PreviewIntelliJ / Xcode
.NET MAUIXAML Hot ReloadありVisual StudioVS / Rider
Lynx高速ありLynx DevToolsChrome ベース

Flutter の Hot Reload は依然として業界トップだ。状態を保持しつつウィジェットツリーを再ビルドする処理が <500ms で終わる。RN Fast Refresh も New Architecture で一段速くなった。


17章 · 性能ベンチマーク — 60fps 維持のコスト

2026 年時点の一般的なベンチマーク (中位クラスの Android 端末、Pixel 6a 相当)。

フレームワークコールドスタートスクロール 60fpsメモリ (ダッシュボード)バッテリ (1 時間使用)
React Native (New Arch + Hermes)~250ms可能~120MB~7%
Flutter (Impeller、AOT)~150ms非常に容易~100MB~6%
Capacitor~400ms困難~150MB~9%
Tauri 2 Mobile~300ms困難~110MB~8%
KMP + ネイティブ UI~120ms最も容易~80MB~5%
Compose Multiplatform~200ms容易~110MB~6%
.NET MAUI~500ms~180MB~10%
Lynx~200ms非常に容易 (スレッド分離)~95MB~6%

ネイティブに近い性能は KMP が圧倒的で、自前レンダラー陣営 (Flutter、Lynx、Compose MP) がそれに続く。WebView 陣営は重いインタラクションで不利。


18章 · 韓国の事例 — トスの RN→ネイティブ移行、カカオトークの RN 採用

トス (Toss) は 2020〜2022 年に RN を積極利用し、一部画面 (送金、カードなど) を RN で構築した。2023〜2024 年のトスの発表によれば、一部の主要画面は RN からネイティブへ再移行された。理由: 60fps 維持の難しさ、決済画面のセキュリティ要件、ネイティブのみで可能なウィジェットやディープリンク統合。ただし、トス証券の一部と社内ツールは依然 RN を使う。

カカオトーク (KakaoTalk) はメッセージ画面をネイティブで維持しつつ、カカオチャンネル、ショッピング、ペイの一部モジュールは RN または WebView で作られている。カカオエンタープライズは 2024 年に KMP 採用の PoC を発表した。

当根マーケット (Karrot) は RN を早期に採用し、2024 年の発表で RN New Architecture を適用後、スクロール性能が約 30% 向上したと述べた。

NAVER LINE の日本本社はメッセンジャーをネイティブで維持しているが、LINE マンガLINE ミュージック の一部画面は Flutter で書かれている。


19章 · 日本の事例 — メルカリ、楽天、ZOZO、Mercari Flutter

メルカリ (Mercari) は 2018 年の Flutter PoC 発表以降、Flutter を一部画面に導入し、2022 年から新しい出品 (listing) フローを Flutter に移行した。2024 年の発表によれば、出品フローの約 70% が Flutter になっている。

楽天 (Rakuten) は巨大なスーパーアプリ生態系を持ち、一部アプリ (楽天キオスク、楽天ペイの一部画面) で Flutter を採用している。ただし楽天本体アプリはネイティブを維持。

ZOZO (ZOZOTOWN) は 2023 年に ZOZOFIT (フィッティングスーツ) アプリを Flutter で作ってリリースした。カメラと 3D モデリングを扱うアプリだが、UI 部分は Flutter、コアはネイティブモジュールに分離している。

LINE マンガ (日本) は一部画面が Flutter で書かれており、コンテンツビューア自体はネイティブを使う。サイバーエージェント (CyberAgent) も一部子会社アプリで Flutter を採用している。

日本は韓国より Flutter 採用率が高い傾向で、メルカリの影響もあり Flutter Tokyo コミュニティが活発だ。


20章 · OTA 更新と App Store ポリシー

iOS App Store と Google Play は「ネイティブコードを OTA で書き換えること」を禁じている。しかし JS バンドルのようなインタプリト型コンテンツは許可されている。だから RN・Capacitor・Tauri・Lynx は OTA 更新が可能だ。

  • Expo EAS Update: RN で最も成熟。ブランチとチャネルでカナリア配信。
  • CodePush (Microsoft、2024 EOL): 運用終了、EAS への移行が推奨。
  • Capacitor Live Updates (Ionic): 有料サービスとして OTA を提供。
  • 自前実装: S3 + バージョンマニフェストで直接構築可能。

OTA の落とし穴は App Store の規約だ。主要機能の変更、決済フローの変更、新カテゴリ追加は正規審査が必要。安全に運用するなら OTA は「バグ修正・文言変更・小さな UI 調整」程度に限定するのが無難。


21章 · 意思決定マトリクス — どのツールをいつ使うか

状況推奨
ネイティブのルック&フィール + 両 OS ガイドに完全準拠KMP + ネイティブ UI
一度書きで 60fps + 豊富なアニメーションFlutter
ウェブチームのコード再利用 + 速い市場投入Capacitor または Tauri 2
React チームがモバイルに進出React Native + Expo
既存の .NET バックエンドチームがモバイルに.NET MAUI
Vue / Angular チームがモバイルにNativeScript または Capacitor
Kotlin チームが iOS もサポートする必要Compose Multiplatform
ByteDance パターンのライブコマース / ミニアプリLynx
Rust バックエンドをモバイルで再利用Tauri 2 Mobile
ゲームUnity、Unreal、Godot (この記事の範囲外)

「これが絶対の正解」というものはない。チームの既存技術スタック、デザインガイド準拠の度合い、市場投入速度、60fps 要件が総合的に決める。


22章 · モノレポ戦略 — Turborepo・Nx・Yarn Workspaces

クロスプラットフォームアプリは通常、ウェブと同じリポジトリに置く。2026 年の標準パターン:

  • Turborepo + pnpm: React Native + Next.js ウェブ + パッケージ共有。
  • Nx: RN、Angular、NativeScript を一緒に使うチームに人気。
  • Yarn Workspaces: シンプルなパターン、ビルドマトリクスが大きくないとき。
  • Melos (Flutter 用): Flutter パッケージのモノレポ専用ツール。
# Turborepo パターン
my-org/
  apps/
    mobile/          # Expo RN アプリ
    web/             # Next.js ウェブ
  packages/
    ui/              # デザインシステム (RN + ウェブ互換)
    api-client/      # 共通 API クライアント
    config/          # ESLint / TS 設定
  turbo.json
  package.json

RN はウェブの React コンポーネントと一部コードを共有できる (react-native-web)。デザインシステム単位でモノレポの真価が発揮される。


23章 · CI/CD — Fastlane・Codemagic・EAS・App Center

iOS ビルドは macOS が必要で、コードサイニングは厄介だ。2026 年の主要オプション:

  • Fastlane: 最古参で最も成熟。セルフホスト、GitHub Actions 連携の双方が可能。
  • Codemagic: Flutter 親和的な SaaS。macOS ビルドマシンを提供。
  • EAS Build (Expo): RN / Expo 特化の SaaS。iOS 証明書を自動管理。
  • Bitrise: iOS / Android 双方に強い。エンタープライズで人気。
  • GitHub Actions + macOS ランナー: 自前で構築。最も自由だが証明書管理は手動。
  • App Center (Microsoft、2025 EOL): 運用終了、別サービスへの移行を推奨。

コードサイニングの落とし穴: Apple Developer アカウント ($99/yr)、Provisioning Profile、プッシュ通知証明書、自動更新が弱い → 期限切れでビルド失敗。Match (Fastlane) で Git に暗号化保存するのが事実上の標準。


24章 · デザインシステム・アクセシビリティ・国際化

フレームワークMaterial DesignCupertino (iOS look)a11yi18n
React NativeRN Paper、TamaguiiOS 標準コンポーネントaccessibilityRolei18next、FormatJS
FlutterMaterial ウィジェット (標準)Cupertino ウィジェット (別途)Semanticsintl パッケージ
Compose MPMaterial 3 (標準)Cupertino 風ライブラリCompose Semanticsmoko-resources
CapacitorIonic ComponentsIonic iOS テーマWeb 標準 ARIAi18next
Tauri 2Web 自由Web 自由Web 標準 ARIAi18next
KMP (ネイティブ)Android はそのままiOS は SwiftUI そのままネイティブツールAndroid resources / iOS Localizable.strings
.NET MAUIMaterial 一部iOS 一部AutomationProperties.resx ファイル
NativeScriptWeb 互換コンポーネントiOS 風コンポーネントARIA 風i18next

アクセシビリティは KMP、.NET MAUI、NativeScript が強い (ネイティブツールをそのまま使う)。Capacitor、Tauri はウェブ a11y 標準に乗る。Flutter は Semantics ウィジェットを明示的に付ける必要がある。


25章 · セキュリティ・認証・決済

モバイルアプリはウェブよりセキュリティ要件が厳しい。

  • Keychain (iOS) / Keystore (Android): トークンやパスワードの安全な保管庫。
  • 生体認証: Face ID、Touch ID、BiometricPrompt。RN は react-native-keychain + react-native-biometrics、Flutter は local_auth
  • アプリ内課金: Apple IAP、Google Billing。RN は react-native-iap、Flutter は in_app_purchase。KMP はネイティブコードを直接呼び出す。
  • プッシュ通知: FCM (Android)、APNs (iOS)。Expo Notifications、Flutter Firebase Messaging。
  • アプリ完全性: iOS DeviceCheck、Android Play Integrity。ルート化・脱獄の検出。

決済画面を RN で作ったチームがしばしば後悔するのは、Apple / Google が IAP 以外の決済に厳しく、RN 画面のセキュリティ監査がネイティブより困難なためだ。トスが一部画面をネイティブに戻した理由のひとつでもある。


26章 · エピローグ — 2027 年の景色

クロスプラットフォームはもはや「一度書いて両方動かす」という単一の約束ではない。2027 年に起こる 3 つの変化:

  1. AI コード生成が両プラットフォームコードのコストを下げる。 Cursor や Claude Code が SwiftUI と Compose を同時に生成するのが当たり前になれば、「コード共有」の価値の一部は侵食される。それでもビジネスロジック共有 (KMP) は依然として魅力的だ。
  2. 自前レンダラー陣営の拡大。 Flutter Impeller が標準になり、Lynx がライブコマースでシェアを広げ、Compose Multiplatform が iOS で安定段階に定着する。
  3. WebView 陣営のルネサンス。 Capacitor 7 と Tauri 2 Mobile は、システム WebView の進化 (WebKit 17、Android WebView 130 以降) とともにシェアを広げる。PWA をモバイルアプリへ移植するコストが最も低い。

最大の教訓はシンプルだ。すべての画面を同じツールで書く必要はない。 トスが決済画面はネイティブ、社内ツールは RN を使うように、一社の中でも画面ごとに適切なツールを選ぶことが 2026 年の答えだ。


References