2026年9月、Shopify Engineeringから「Native is now the future of mobile at Shopify」という記事が公開されました。
https://shopify.engineering/back-to-native
Shopifyは2020年にモバイルアプリ開発をReact Nativeへ寄せる方針を打ち出し、React Nativeコミュニティにも大きな投資を続けてきた会社です。そのShopifyがSwiftとKotlinを使ったネイティブ開発へ戻るというのですから、なかなかインパクトのある話です。
このニュースを受けて「やはりReact NativeやFlutterのようなクロスプラットフォーム開発には無理がある」「これからはネイティブだ」といった反応も見かけるようになりました。
しかし、Shopifyの記事を読む限り、Shopify自身はそんな話をしていません。
むしろ筆者には、この記事は クロスプラットフォーム開発によって何のコストを削減しているのかを改めて考えるための、とてもよい教材 に見えました。
React NativeもFlutterもただの技術です。役に立つなら使えばいいし、割に合わなくなったらやめればいい。
では、その「割に合う・合わない」は、どうやって考えればよいのでしょうか。
Shopifyは「React Nativeは失敗だった」と言っていない
まず、ここは大事なので確認しておきましょう。
Shopifyは2020年にReact Nativeを選んだ判断について、当時としては正しい選択だったと振り返っています。
当時の課題のひとつは、iOSとAndroidで同じ機能を二度実装し、それぞれを同期させ続けることでした。React Nativeによって、一度の実装で両プラットフォームへ機能を届けやすくなり、Webを中心に働いていた開発者もモバイル開発へ参加しやすくなりました。
一方でReact Nativeにも、フレームワークのアップデート追従、ネイティブ層との境界、外部ライブラリへの依存、パフォーマンス上の問題などのコストがあります。
これらは2020年にも存在していました。それでもネイティブアプリを2本開発するコストを削減できるメリットのほうが大きかった。だからReact Nativeを選んだわけです。
ところが2026年、その天秤が動きました。
ShopifyではCoding Agentを開発プロセスへ深く組み込み、片方の実装を参考にもう片方を実装したり、テストやレビューを通して両者の挙動を揃えたりする仕組みを整えています。
ネイティブアプリを2本作るコストがゼロになったわけではないけれど、2020年ほど高くはなくなった。一方でReact Nativeを使うコストは依然として存在する。結果として天秤が逆側へ傾いた。
これは「React Nativeがダメだった」という話ではありません。技術選定の前提となっていたコスト構造が変わったという話です。
技術を導入しても、コストは消滅しない
筆者は以前から、クロスプラットフォーム開発について「コードを何割共有できるか」だけを見るのは、あまりよくないと思っています。
たとえばiOSとAndroidをそれぞれネイティブで開発すると、「同じ画面をSwiftとKotlinで2回書く」という実装コストがあります。しかし、二重になるものはコードだけではありません。
仕様変更を両方へ反映し、挙動が揃っていることを確認し、バグ修正も同期させる必要があります。さらに、プラットフォームごとにUIや操作方法が異なれば、サポートセンター向けマニュアルをそれぞれ用意したり、カスタマーサポートのメンバーに両方の操作方法を教育したりするコストも増えていきます。
逆にReact NativeやFlutterを採用すれば全部が解決するわけでもありません。ネイティブAPIやOSアップデートへの対応は残りますし、クロスプラットフォームフレームワーク自身のアップデートという仕事も増えます。抽象化の境界から問題が漏れ出せば、結局SwiftやKotlinの世界まで降りていくこともあります。
技術によってコストが魔法のように消滅するわけではありません。
ある場所で払っていたコストを、別の場所で払うように移動させていると考えたほうが実態に近いと思います。
クロスプラットフォーム開発は何を安くできるのか
実装コスト
もっとも分かりやすいものです。同じビジネスロジックやUIをiOSとAndroidでそれぞれ実装する代わりに、共通コードとして一度だけ実装します。
Coding Agentが得意なのもこの領域です。「このiOS版と同じ機能をAndroidにも作って」と頼んで実装できるようになれば、コードを共有することによる相対的なメリットは小さくなります。
ただし、コードを生成するコストが下がることと、そのコードを保守するコストが下がることは同じではありません。
同期コスト
筆者はこちらのほうが重要になるプロジェクトも多いと思っています。
2つのコードベースがあれば、「同じ仕様で動いている状態」を維持する必要があります。片方だけ新機能やバグ修正が漏れたり、実装者が仕様を少し違って解釈したりすることは普通に起こり得ます。
共通コードにしてしまえば、共通化された範囲ではこの問題をかなり減らせます。
一方、ShopifyのようにCoding Agent、テスト、レビュー、開発基盤を組み合わせて2つの実装のparityを維持できるなら、ここも別の方法で安くできます。
重要なのは Coding Agentを導入しただけで同期コストが消えるわけではない という点です。
ShopifyはAgentにコードを書かせるだけでなく、checkpoint、テスト、visual review、複数系統のcode review、人間による承認などを組み合わせています。ネイティブ2本を維持するコストを下げるための開発基盤そのものに投資しています。
「Shopifyができた」ことと「自分たちも明日からできる」ことの間には、それなりの距離があります。
品質保証コスト
ビジネスロジックを共通コードとして持てることは、QAのコストにも影響します。
もちろん、React NativeやFlutterを採用したからといって、iOSとAndroidの片方だけテストすればよいわけではありません。UI、OSのAPI、ライフサイクル、端末差など、プラットフォームごとに確認すべき領域は残ります。
一方で、両プラットフォームでまったく同じビジネスロジックのコードが動いているなら、「この計算や判定についてはiOS側で十分に確認できているので、Android側では同等ケースの一部を間引く」といった判断はしやすくなります。QAのリソースが足りないときに、共通部分よりプラットフォーム固有部分へ重点的に時間を使う、といった配分もできます。
ネイティブで同じ仕様を2つ実装した場合は、仕様が同じでもコードは別物です。片方のQA結果をもう片方にも適用してよい、と判断するためには、より強い根拠が必要になります。
共通コードはQAを不要にするものではありませんが、「同じ実装である」という事実を、テストの重複を減らすための根拠にできることがあります。
ただし、Shopifyがこの問題を考えていないわけではありません。二実装になれば、AgentがiOS側とAndroid側にそれぞれ別のバグを作り込む可能性もあります。だからこそShopifyは、テストやvisual review、parityの確認などに投資して、その差分を検出するための仕組みを整えています。
つまり、ネイティブ二実装を選ぶならQAコストがそのまま倍になる、という単純な話でもありません。二実装によって増える品質保証の負担を、テスト基盤や自動化への投資で別のコストへ移していると見るほうが、この記事全体の考え方にも合っています。
学習コストとコンテキストスイッチ
クロスプラットフォーム技術で共有できるのは、コードだけではありません。
少し極端な例として、iOSとAndroidでUIコードをまったく共有しないReact Nativeアプリを考えてみます。
iOS React NativeでiOS向けUIを実装
Android React NativeでAndroid向けUIを実装
コード共有率だけをKPIにするなら失敗に見えるかもしれません。しかし開発者から見ると意味があります。
どちらでもReactのコンポーネントモデルを使い、同じようにstateや非同期処理を扱い、同じようにスタイリングできます。iOS担当者がAndroid側を手伝うときに、SwiftUIからJetpack Composeへ頭を切り替える必要がない。Reactの知識を持ったまま移動できます。
ここで共有しているのは ソースコードではなく、開発者の知識 です。
このように コードを共有せず、開発モデルを共有する ことにも十分な価値があります。
ちなみに筆者の記憶では、Microsoft OfficeのReact Native活用でもこれに近い考え方が採用されていたはずです。今回あらためて調べたところ、OfficeがC++による共通ロジックとReact Nativeを組み合わせていることまでは確認できましたが、「コードではなく開発者の知識を共有する」という意図を示す一次情報までは見つけられませんでした。記憶違いだったらごめんなさい。
人材・組織のコスト
たとえば社内にReactを書けるWebエンジニアが10人いて、SwiftやKotlinに詳しい人がほとんどいない組織を考えます。
この会社にとってのReact Nativeの価値と、iOS/Androidそれぞれの専門家が十分に揃っている会社にとっての価値は当然違います。
ネイティブ開発を選ぶなら、採用する、育成する、あるいは既存メンバーに新しい技術を学んでもらう必要があります。iOSチームとAndroidチームを分ければ、チーム間のコミュニケーションやスケジュール調整も必要になります。
クロスプラットフォーム技術はこれらを消すものではありませんが、必要な専門性の境界を動かすことはできます。
クロスプラットフォーム開発が解決しないコスト
React NativeやFlutterを採用しても、App StoreとGoogle Playは別々に存在します。署名や審査、配布の仕組みも違います。Push Notification、Deep Link、権限、バックグラウンド処理など、OS固有の仕組みから逃れられない領域もあります。
実機でしか起きない問題もありますし、OSアップデートによって突然挙動が変わることもあります。
「コードが1つになったからモバイルアプリが1つになった」わけではありません。ユーザーが使っているのは、あくまでiOSアプリとAndroidアプリです。
テストやリリース、ストア運用、プラットフォーム固有の品質保証といったコストは残ります。
このあたりを無視して「コードが半分だから開発費も半分」と見積もると、だいたい悲しいことになります。
クロスプラットフォームだから増えるコスト
さらに、クロスプラットフォーム技術を採用することで新しく発生するコストもあります。
React NativeであればReact Nativeそのもの、FlutterであればFlutterそのものが、アプリとOSの間に入ります。
抽象化がうまく機能している間は便利ですが、プラットフォーム固有機能や性能問題、フレームワークのバグに遭遇すると、その境界を越える必要があります。フレームワークや依存ライブラリのアップデートにも追従しなければなりません。
つまり、ネイティブ2本を維持するコストを減らす代わりに、クロスプラットフォームという追加のレイヤーを維持するコストを引き受けています。
これはReact NativeやFlutterが悪いという意味ではありません。便利な抽象化には、その抽象化を維持するコストがあります。
問題は、そのコストを払うことで何を安くできるのかです。
Coding Agentは天秤を動かす
Shopifyの話へ戻ります。
Coding Agentによって、同じ機能をSwiftとKotlinで二度書く作業は以前より確実に安くなるでしょう。片方を参考にもう片方を生成したり、普段使わない言語をAgentに助けてもらいながら実装したりできます。
これはクロスプラットフォーム技術が持っていたメリットの一部を小さくします。
しかし、コードを2回生成できても仕様が2つに分裂しないことは保証されません。生成されたコードを誰がレビューするのか、数年後に誰が保守するのか、OSごとの不具合を誰が調査するのか、という問題も残ります。
また「開発者の知識を共有する」「組織内で人を移動しやすくする」といった価値は、単純なコード生成能力だけでは測れません。
Shopifyは、それらも含めてNativeへ戻るための開発基盤を作り、そのコストを受け止められる組織を育てたのでしょう。
あなたの組織も同じでしょうか。
「どちらが正しいか」ではなく「何を安くしたいか」
クロスプラットフォーム開発については、昔から宗教戦争になりがちです。
ネイティブのほうがよい。React Nativeのほうが速く作れる。Flutterなら全部同じにできる。いや、結局ネイティブを書くことになる。
どれも、条件によっては正しいでしょう。
しかし技術選定で知りたいのは、一般論としてどちらが優れているかではありません。
自分たちのプロダクトと組織では、いま何に一番お金や時間を使っているのか。そのコストを技術によってどこへ移動させると、全体として安くなるのか。
見るべきなのはそこです。
ShopifyにとってReact Nativeは2020年には合理的な選択でした。そして2026年には、Coding Agentと開発基盤によってNativeを選ぶほうが合理的になった。
それは「React Nativeの時代が終わった」という意味ではなく、Shopifyにとっての最適解が変わったということです。
他社が同じ結論へ行くとは限りません。組織の人数も、持っているスキルも、プロダクトの性質も、求めるUIも、許容できるコストも違うからです。
React NativeもFlutterも、SwiftもKotlinも、ただの技術です。
流行や有名企業の結論をそのまま輸入するのではなく、自分たちが何のコストを解決したいのかを考えて、役立つものを使えばよいのだと思います。
Discussion
