アプリ開発、AI で書けるなら Swift と Kotlin で分けて書けばいいのか
こんにちは、わさびーふです。
AI に Swift と Kotlin をそれぞれ書かせれば、iOS と Android を別々に作っても、以前ほどコストはかからないんじゃないか。そうなると、Flutter や React Native でコードを共有する理由はどこまで残るんだろう、という話です。
きっかけになるのが、AI を使ってネイティブへ戻った Shopify と、コード共有の価値を論じた Flutter チームの記事 です。選んでいる技術は違いますが、両方とも、変更した結果をどう確認するかにかなり力を入れています。
だとすると、差がつくのは Swift や Dart を書く速さだけではなさそうです。同じ仕様を維持するために、コードを共有するのか、仕様やテストを共有して実装は分けるのか。ここを考えてみたいです。
2026 年 11 月 6 日までの公開情報を読んで考えた記事です。各方式の工数や性能を自分で比較計測したものではありません。移行事例で実装負担の軽減は報告されていますが、長期の総コストまで下がったと確認できたわけではありません。
Shopify は React Native からネイティブへ戻った
Shopify は 2026 年 9 月の発表 で、モバイルアプリを Swift / Kotlin へ移行する方針を示しています。
React Native で同じ機能を一度だけ作れる利点は認めたうえで、coding agents が二実装の負担を下げ、技術選定の前提が変わったと説明しています。二つのプラットフォームを維持するコストが消えた、とまでは言っていません。
Shop アプリでは、React Native の New Architecture 対応へ投資するタイミングとも重なっていました。その対応に進む前に、AI を使ったネイティブ化を試しています。既存の構成をそのまま使い続ける場合との比較ではなく、React Native を継続する側にも更新のための投資が必要だったわけです。移行の背景
Shop アプリは移行済みで、同報告によると PoC からストア公開まで 12 週間。中心となったのは 6 人のエンジニアで、途中から機能チームも検証に参加しています。
12 週間という期間と一緒に読みたいのが、移行用の検証基盤です。既存実装から仕様を整理して計画をレビューし、スクリーンショットや分析イベントまで比較しています。ネイティブの専門知識も必要だったとしています。
これを「コード共有が不要になった」とだけ読むと、移行のために用意した仕組みが抜けます。報告にある具体的な比較対象は旧 React Native 版と新ネイティブ版です。移行後も iOS / Android の機能をそろえる方針は示されていますが、その長期運用の成果まで確認できたわけではありません。
Spotify は「書き換え」ではなく、開発自動化の事例
2026 年 2 月の決算説明資料 では、通勤中に Slack から Claude へ iOS アプリの変更を依頼し、返ってきたビルドをエンジニアがテストする「Honk」を紹介しています。
さらに 6 月の Engineering Blog では、Claude Agent SDK と独自の実行基盤、複数 OS の CI ビルドを組み合わせた構成を説明しています。PR 作成頻度が 76% 増え、レビューや意思決定が新たな制約になっているとも報告しています。
これはクロスプラットフォームからの移行事例ではなく、既存の開発基盤へ AI を組み込んだ事例です。PR 数を開発速度や費用の改善率には置き換えられませんが、コードの生成量が増えたあと、どこに人間の仕事が残るかを示しています。
Flutter 側が問うているのは、移植したあとのこと
Flutter チームの 2026 年 10 月 20 日の記事 は、移植が速くなることと、長期にわたって維持しやすいことを分けて論じています。
Shopify が二実装を運用できると判断したのに対して、こちらは一つの実装に保つ価値を説明しています。同じ問題に別の対処をしている、と考えると両方を読みやすくなります。
コードには、仕様書に戻っていない判断も残っている
公式記事は、長く運用されたコードを、仕様判断や障害対応が積み重なった組織の記憶として捉えています。記事が引用する Eric Seidel の論考 も、ソフトウェアに込められた意図を複数環境で保つことを扱っています。
たとえば、認証が切れたときに何を保存してログイン画面へ戻すか、古いキャッシュをいつ捨てるか。こうした対応は、最新の画面仕様だけを読んでも分からないことがあります。
AI が既存コードを参照できることは助けになりますが、書き換えた先へその条件が残ったかは確認が必要です。初回の移行だけでなく、その後に見つかった例外処理を両方へ反映する仕事も続きます。
書き換えを検討するとき、画面の再現だけでなく、こうした条件をどこまで引き継げるかも確認したいです。
同じ指示でも、二つの実装が同じ振る舞いになるとは限らない
公式記事は、別々のエージェントが同じ仕様から違う挙動を実装する問題も挙げています。記事中の購入処理や売上への影響は説明用の例で、実在企業の障害報告としては扱いません。
ただし、共有コードならすべての挙動差が消えるわけでもありません。ライフサイクル、権限、バックグラウンド実行など、OS 側の違いは残ります。共有によって減らせるのは、主に共有したロジックを独立に実装することで生じる差です。
Shopify の方針記事は、共通仕様・テスト・レビューでプラットフォーム間の同等性を維持する負担が下がったと説明しています。一方、Flutter 側は実装を集約する価値を説明しています。維持費の比較データではありませんが、同じ問題に異なる手段を選んでいる点は興味深いです。
AI にとっても、変更結果を早く確かめられることに価値がある
もう一つの論点は、生成したコードを検証するまでの速さです。Flutter は状態を保った変更反映や Widget test を、その強みとして挙げています。
たとえば、入力途中でしか再現しないレイアウトの不具合なら、修正するたびにログインや画面遷移をやり直すより、その状態で確認できる方が反復しやすいです。コードを AI が書いても、この待ち時間や再現の手間は効きます。
ただ、hot reload はすべての変更に使えるわけではありません。Flutter の公式ドキュメントでも、ネイティブコードの変更などには full restart が必要とされています。Hot reload 後の状態と、新規起動時の動作を分けて確認する必要もあります。Hot reload の適用範囲
公式記事には検証時間の比較表もありますが、変更内容やテストの種類をそろえた、あらゆる環境に適用できる性能差とは読みません。Android にも emulator を使わず JVM 上で動かす local unit test があります。「ネイティブのテストは常に端末の起動が必要」という比較はできません。Android の local unit test
ここで比べたいのは、同じ不具合を再現し、修正し、正しくなったと判定するまでの一往復です。アプリの動作性能とは別に、開発中のこの速さも測りたいです。
ストア評価が同じでも、性能が同じとは限らない
公式記事は、Apptopia のデータをもとに Flutter 製と非 Flutter 製アプリの平均ストア評価が同じだったと紹介しています。記事に掲載された丸め後の平均値には、差がないという結果です。
ただし、「非 Flutter」には React Native なども入りえます。ネイティブだけとの比較ではなく、アプリの用途や規模をそろえた実験でもありません。平均評価から起動時間、メモリ、入力遅延の同等性までは判断できません。
ユーザーの評価と、特定の処理で出せる性能は分けて見る。この点は、後で紹介する Shop アプリの数値を読むときも同じです。
検索画面の変更なら、何を共有したいか
ここからは、選定するときに試す例として考えてみます。実際に比較実験をした結果ではありません。
最初は「入力して検索ボタンを押す」画面だったものを、「入力が止まったら検索する」画面へ変えるとします。検索中に次の文字が入力されるので、リクエストが重なります。
たとえば ca の検索を始め、そのあと cat を検索したとき、cat の応答が先に返る。最後に届いた ca の結果で上書きしてしまうと、入力と検索結果が食い違います。
この変更で欲しいのは、単に二つの画面が同じように見えることではありません。
| 起こす条件 | 確認したい振る舞い |
|---|---|
| 新しい検索のあとに古い成功応答が届く | 古い結果で表示を上書きしない |
| 新しい検索が成功したあと、古い検索が失敗する | 古いエラーを表示しない |
| 検索中に入力を空にする | 遅れてきた結果で一覧を復活させない |
| 入力を変えずに再検索する | 同じ文字列でも、前回と今回のリクエストを区別する |
最後の条件まで入れると、検索文字列が一致しているかだけでは足りません。リクエスト単位の識別などで、どの応答を採用するかを決める必要があります。処理を cancel する設計なら、その取り消しがどこまで保証されるかも確認します。
Flutter / React Native でこの制御を共有しているなら、一つの状態遷移を修正して、上の条件をテストできます。ただし、入力イベントや画面を離れたときの処理は各 OS でも確かめます。
Swift / Kotlin で分けるなら、同じイベント順序と期待値を両方のテストへ渡す方法が考えられます。実装は違っても、応答順を意図的に入れ替えて同じ条件を確認できます。それぞれの実装に合わせて AI が別々の期待値を作るだけでは、比較になりません。
どちらの方式でも、iOS / Android のビルドと統合・画面確認は残ります。共有コードなら状態遷移のテストをまとめられますが、それだけで各 OS の入力やライフサイクルまで確認できるわけではありません。実装を分ける場合は、同じイベント順序と期待値を二つの実装へ適用するテストも維持します。
こうして見ると、共有コードの利点はこの制御を一つに保てることです。一方、ネイティブでも契約をテストで共有できれば、二実装の差を調べる負担は下げられます。検証基盤が必要なのは両方で、違うのは共通ロジックを一つの実装で確認するか、二つの実装で確認するかです。
この例で比較するなら、まず「古い結果を採用しない」という仕様を決める時間は共通です。そのあとに、状態管理の修正、応答順を制御するテストデータの用意、テスト実行と失敗の調査、各 OS の画面確認に分けて作業を記録します。
共有した制御を一度直す方が楽だったのか、既存の Swift / Kotlin のテストへ同じ条件を追加する方が楽だったのか。AI を待つ時間と、人間が判断・修正する時間も分けておけば、コードの生成速度以外を比べられます。
この検索の例で分かるのは、共通ロジックへの変更の扱いやすさです。カメラ処理の性能や OS 固有の体験まで、この結果だけで選ぶつもりはありません。ただ、最初の画面が完成するまでよりも、二回目の要求を入れたときの方が、維持の負担は見えそうです。
パフォーマンスは、必要な水準までの工数で考える
ネイティブへ移行する理由として、パフォーマンスも無視できません。
Shopify が公表した Shop アプリの数値は以下です。起動時間は、アイコンをタップして最初のホームフィードが見えるまでの時間です。
| 指標 | React Native 版 | ネイティブ版 |
|---|---|---|
| iOS 起動時間 | 3,200 ms | 2,466 ms |
| Android 起動時間 | 4,433 ms | 2,233 ms |
| Android release build サイズ | 293 MB | 184 MB |
出典:Shop アプリの移行報告。iOS の build サイズは逆に 67 MB から 68 MB へ増えています。
同報告では、Android の release build 時間も約 75% 短縮し、iOS はほぼ同じだったとしています。Release build の結果なので、日常の差分ビルドや hot reload との直接比較はできません。それでも、ネイティブ化によって build の待ち時間が減ったという成果は、変更から検証までの工数を考えるうえで押さえておきたいです。
このアプリでは改善が出ています。ただ、移行時に画面の廃止や簡素化もしているので、数字の差をすべて言語や framework の差に帰属させることはできません。AI を使えば、どのアプリでも同じ期間・同じ改善幅で移行できるという結果でもありません。
Flutter と React Native も分けて見る
Flutter と React Native は描画や実行の構造が異なります。Flutter は基本的に自身の描画基盤で Widget を描き、React Native は標準のコンポーネントでプラットフォーム側の View を利用します。独自描画やネイティブコードを組み合わせる実装もあるため、使っている機能まで見て比較する必要があります。Flutter の構造 / React Native のコンポーネント
React Native 製の一つのアプリで起動時間が改善したことから、Flutter を含めて「クロスプラットフォームはこのくらい遅い」とは言えません。逆に、共有コードで十分な性能が出たアプリがあっても、別のアプリのカメラ処理や入力応答まで保証するわけではありません。
見たい指標も分かれます。
- 起動:プロセスが立ち上がるまでか、データを取得して操作できるまでか
- 描画:平均 FPS だけでなく、操作中のフレーム落ちや長い停止がないか
- メモリ:画像・動画の利用中にどこまで増え、不要になったあと戻るか
- 入力やメディア処理:タップへの反応、音声の遅延、撮影中の安定性など
どの方式でも対象端末と測定条件をそろえる必要があります。さらに、release build のファイルサイズとユーザーがストアからダウンロードするサイズは区別したいです。Flutter のアプリサイズ計測ガイド
最適化にかかる時間もコスト
ここは AI によって選択が変わりそうな部分です。
ネイティブを二つ実装する負担が下がるなら、OS の API や公式ツールへ直接アクセスできる構成を選びやすくなります。共有層とネイティブ層をまたぐ問題が多いアプリなら、その境界を減らす価値もあります。
一方で、両 OS の独自 UI を共通の描画・状態管理で作れることが、実装や調整の負担を減らす場合もあります。OS ごとに最適化するなら、その変更を両方で維持する費用も見ます。
最高性能をどこまで出せるかと、必要な性能までどのくらいの工数で到達できるかは、別の問いです。自分たちのアプリで重い処理を一つ作り、調査と修正まで試さないと、ここは判断しづらいです。
共有した方にも、framework の更新や plugin の互換性を保つ仕事は残ります。性能問題のたびに共有層とネイティブ層を往復しているなら、その調査に使った時間も二重実装の費用と並べたいです。
どちらにも同じ AI ツールと検証の準備を与えないと、この比較はできません。Flutter 公式記事も Shopify の報告も判断材料にはなりますが、同じアプリを同条件で維持した総コストの比較実験ではありません。
補足:Airbnb / Dropbox / Udacity の撤退事例
最近の話と混ざりやすいので、以前の事例も整理しておきます。
| 事例 | 公表された内容 | 今回の話での位置づけ |
|---|---|---|
| Airbnb、2018 年 | アプリ内の React Native 採用部分を段階的にネイティブへ移す方針 | 技術・組織・統合基盤の負担。AI 普及前の判断 |
| Dropbox、2019 年 | C++ によるモバイル共有コード戦略から、主に Swift / Kotlin へ転換 | 独自基盤の保守負担。Flutter / React Native の撤退例ではない |
| Udacity、2018 年 | 最後の React Native 製機能を終了し、採用をやめた | その機能の置き換えは不要だったため、全面書き換えの事例ではない |
Airbnb の記事にも、当時の技術的な指摘を現在の選定へ使うなら再検証するよう注意書きがあります。これらの話から、今の Flutter / React Native が一般に不利だとは言えません。
逆向きの例もあります。Caribou Coffee の事例 では、Titanium から Swift / Kotlin へ移行したあと、機能の同等性を維持する負担から Flutter を選んでいます。これも AI 時代の費用比較ではありませんが、アプリと組織によって負担の大きい場所が違うことは分かります。
何を共有するかも選べる
選択肢は、すべてを Flutter / React Native にするか、すべてを Swift / Kotlin で別々に作るかの二つだけではありません。
UI は別にしてロジックを共有する、実装は別でも仕様とテストデータを共有する、OS 固有の機能だけネイティブに切り出す方法もあります。Kotlin Multiplatform も、共有ロジックの上にネイティブ UI を載せる構成をサポートしています。JetBrains の構成例
頻繁に変わる購入フローを一つに保ちたいのか、カメラ処理を各 OS に合わせて作りたいのか、Web でも同じ機能を届けたいのか。共有の範囲は、そうした要求から決める方がよさそうです。
新規開発の方式を選ぶ話と、既存アプリを移行する話も分けます。既存実装は AI が参照できる仕様になりますが、移行には既存ユーザーのデータやログイン状態を引き継ぎ、以前の挙動を確認する仕事もあります。
クロスプラットフォームを選ぶなら
AI でコードを書く負担が下がっても、共通の仕様を一つの実装に保つ価値は残ります。検索結果の採用条件や購入状態の復元など、両 OS で同じであってほしい処理を、変更のたびに別々に直さずに済むからです。
両 OS で同じ機能を頻繁に変えていくなら、Flutter / React Native を選ぶ理由になります。もちろん、OS ごとの動作確認や framework・plugin の更新は残ります。その負担を含めても、共有した方が変更を追いやすいかで判断したいです。
ネイティブを選ぶなら
AI が二重実装の負担を下げるなら、各 OS の API や公式ツールを直接使える利点を、以前より取りやすくなります。
OS 固有の機能や操作感が商品の中心だったり、共有層との境界で調査や最適化に時間を使っていたりするなら、Swift / Kotlin で分ける理由があります。Shopify の事例は、その判断が実際に成立した例です。ただし、実装を分けたあとの仕様の同期と検証は必要です。そこを既存のチームと開発基盤で担えるかも、選定に含めます。
自分は、変更してから確かめるまでを見たい
どちらの選び方にも理由がありますが、自分が今から選ぶなら、コードを生成する速さよりも、仕様変更を入れて検証し終えるまでの手間を重く見ます。
難しい機能を一つ作って、動いたところで終わりにせず、もう一度要求を変えてみる。検索なら応答順を入れ替える条件を足す。カメラなら撮影中の中断や復帰も試す。そのとき、何を修正して、どこまで確認し直す必要があるのかを見たいです。
結果としてネイティブの方が扱いやすいならそちらを選ぶし、共有コードで変更をまとめられる方が楽なら Flutter / React Native を選ぶ。少人数だから共有、大企業だからネイティブ、とも決めません。
もちろん、一度の試作で長期の維持費まで分かるわけではありません。それでも、生成できたコードの量だけで選ぶより、変更と検証まで試す方が判断材料になります。
Shopify から学びたいのも、ネイティブへ戻ったという結論だけではありません。以前は合理的だった選定を、道具が変わったことで見直したところです。AI があるから書き換えるのではなく、以前の選定理由が今も成立するかを問い直す。 今回の事例を読んで、自分が選定で意識したいのはそこです。
おしまい