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

- Name
- Youngju Kim
- @fjvbn20031
プロローグ — 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 | 初回フレーム jank | 60fps の難易度 |
|---|---|---|---|---|
| React Native (New Arch) | ネイティブビュー + Fabric | UIKit / Android Views | 低 | 中 |
| Flutter (Impeller) | 自前レンダラー | Metal / Vulkan | 非常に低 | 易 |
| Capacitor | WebView | WebKit / Blink | 中 | 中 |
| Tauri 2 Mobile | WebView | WebKit / Blink | 中 | 中 |
| Compose Multiplatform | Skia | Metal / 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 .ipa | Android .apk | 備考 |
|---|---|---|---|
| React Native (Hermes) | ~10MB | ~7MB | Hermes バイトコードを含む |
| Flutter (Impeller、AOT) | ~15MB | ~9MB | Dart ランタイム + アイコンフォント |
| Capacitor | ~5MB | ~3MB | WebView 自体は OS 提供 |
| Tauri 2 Mobile | ~4MB | ~3MB | Rust 静的リンク |
| KMP (ネイティブ UI) | ~3MB | ~2MB | ネイティブが基本 |
| Compose Multiplatform | ~12MB | ~5MB | iOS は Skia を含む |
| .NET MAUI | ~25MB | ~15MB | .NET ランタイムが大きい |
| NativeScript | ~10MB | ~8MB | JS エンジンを含む |
| Lynx | ~8MB | ~6MB | 自前レンダラー |
KMP (ネイティブ UI) と Capacitor / Tauri (WebView) が最も小さい。.NET MAUI が最も大きい。
15章 · ネイティブモジュール・ブリッジ — どうやってネイティブにアクセスするか
各フレームワークがネイティブ機能にアクセスする方法。
| フレームワーク | メカニズム | 実装言語 | 型安全性 |
|---|---|---|---|
| React Native (TurboModules) | JSI HostObject | Obj-C++ / Java / Kotlin / Swift | codegen による強 |
| Flutter | Platform Channels (MethodChannel) | Swift / Kotlin | シリアライゼーションベース、手動 |
| Capacitor | Capacitor Plugin | Swift / Java | デコレータベース、中 |
| Tauri 2 | Command と IPC | Rust | Serde ベースで強 |
| KMP / Compose MP | expect / actual | Kotlin / Swift interop | Kotlin の型そのまま |
| .NET MAUI | DependencyService / Handler | C# | C# の型そのまま |
| NativeScript | メタデータ + リフレクション | JS + Obj-C / Java メタデータ | ランタイム |
| Lynx | Native Module | Swift / Kotlin | TypeScript 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 Reload | Hot Restart | DevTools | デバッガ |
|---|---|---|---|---|
| React Native | Fast Refresh | あり | React DevTools | Chrome / Flipper / Reactotron |
| Flutter | 非常に高速 | あり | Flutter DevTools | Dart DevTools |
| Capacitor | ウェブと同じ | あり | ブラウザ DevTools | Chrome / Safari |
| Tauri 2 Mobile | 高速 | あり | Web + Rust 両方 | Web DevTools + lldb |
| KMP | 通常の IDE | あり | Android Studio / Xcode | 両方のデバッガ |
| Compose Multiplatform | 高速 | あり | Compose Preview | IntelliJ / Xcode |
| .NET MAUI | XAML Hot Reload | あり | Visual Studio | VS / Rider |
| Lynx | 高速 | あり | Lynx DevTools | Chrome ベース |
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 Design | Cupertino (iOS look) | a11y | i18n |
|---|---|---|---|---|
| React Native | RN Paper、Tamagui | iOS 標準コンポーネント | accessibilityRole | i18next、FormatJS |
| Flutter | Material ウィジェット (標準) | Cupertino ウィジェット (別途) | Semantics | intl パッケージ |
| Compose MP | Material 3 (標準) | Cupertino 風ライブラリ | Compose Semantics | moko-resources |
| Capacitor | Ionic Components | Ionic iOS テーマ | Web 標準 ARIA | i18next |
| Tauri 2 | Web 自由 | Web 自由 | Web 標準 ARIA | i18next |
| KMP (ネイティブ) | Android はそのまま | iOS は SwiftUI そのまま | ネイティブツール | Android resources / iOS Localizable.strings |
| .NET MAUI | Material 一部 | iOS 一部 | AutomationProperties | .resx ファイル |
| NativeScript | Web 互換コンポーネント | 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 つの変化:
- AI コード生成が両プラットフォームコードのコストを下げる。 Cursor や Claude Code が SwiftUI と Compose を同時に生成するのが当たり前になれば、「コード共有」の価値の一部は侵食される。それでもビジネスロジック共有 (KMP) は依然として魅力的だ。
- 自前レンダラー陣営の拡大。 Flutter Impeller が標準になり、Lynx がライブコマースでシェアを広げ、Compose Multiplatform が iOS で安定段階に定着する。
- WebView 陣営のルネサンス。 Capacitor 7 と Tauri 2 Mobile は、システム WebView の進化 (WebKit 17、Android WebView 130 以降) とともにシェアを広げる。PWA をモバイルアプリへ移植するコストが最も低い。
最大の教訓はシンプルだ。すべての画面を同じツールで書く必要はない。 トスが決済画面はネイティブ、社内ツールは RN を使うように、一社の中でも画面ごとに適切なツールを選ぶことが 2026 年の答えだ。
References
- React Native documentation — New Architecture. https://reactnative.dev/architecture/landing-page
- React Native New Architecture migration guide. https://reactnative.dev/docs/new-architecture-intro
- Hermes documentation. https://hermesengine.dev
- Flutter documentation. https://flutter.dev
- Flutter Impeller renderer overview. https://docs.flutter.dev/perf/impeller
- Expo documentation. https://docs.expo.dev
- Expo Router. https://docs.expo.dev/router/introduction/
- EAS Build and Update. https://docs.expo.dev/eas/
- Capacitor documentation. https://capacitorjs.com/docs
- Ionic Framework. https://ionicframework.com/docs
- Tauri 2 documentation. https://tauri.app/start/
- Tauri 2 mobile development. https://tauri.app/develop/
- Kotlin Multiplatform official. https://kotlinlang.org/lp/multiplatform/
- Compose Multiplatform. https://www.jetbrains.com/compose-multiplatform/
- .NET MAUI documentation. https://learn.microsoft.com/dotnet/maui/
- NativeScript documentation. https://docs.nativescript.org
- Lynx (ByteDance) — Lynx Framework. https://lynxjs.org
- Mercari Engineering — Flutter adoption. https://engineering.mercari.com
- Toss Tech blog — React Native experience. https://toss.tech
- LINE Engineering Blog — mobile platform stories. https://engineering.linecorp.com