はじめに
『ホットペッパーグルメ』開発グループマネージャーの永井です。
先日開催したRECRUIT TECH CONFERENCE 2025- 技術を活かす現場力はご覧いただけたでしょうか。開催からしばらく経ち、『Flutter/KMPを用いたアジリティ追求の軌跡』セッションに登壇した3名でマルチプラットフォーム開発に関する追加の対談を行いました。今回はその内容を記事としてまとめます。
テーマは以下の3つです。
- マルチプラットフォーム化で実はモヤモヤしている部分・うまくいっていない部分
- マルチプラットフォーム化を推進しているエンジニアが「この場合はやめておいた方がいい」と思うプロダクト特性
- マルチプラットフォーム化の今後の展望
登場人物
- 永井 佑樹(ファシリテーター/飲食領域)
- 桐山 圭祐(旅行領域)
- 若宮 浩司(まなび領域)
1. うまくいっていない部分
永井:
では最初は、「マルチプラットフォーム化で実はモヤモヤしている部分」について話していきましょうか。桐山さんからお願いします。
桐山:
はい。たとえばFlutterでiOS・Androidを共通化しても、必ずしも工数が半分になるわけではないという点があります。Flutterにリプレイスする前のネイティブ実装では、ABテストを行う際にまずiOSだけ実装し、良い結果が出たらAndroidにも展開する、という運用をしていました。 Flutterに移行した今もその運用は変わっていないため、検証段階では従来と比べて工数が大きく削減されるわけではないんですよね。 もちろん、ABテストで良い結果が出てAndroidにも展開するフェーズでは、Flutterのおかげで追加の実装コストがほぼゼロになるというメリットはあります。
永井:
FlutterならiOS・Androidの両方で同時にABテストを実施して、検証期間を短縮することもできそうですが、そういう運用にはしていないんですか?
桐山:
はい、今は基本的にやっていません。両OSで検証を行う場合、それぞれの試験が必要になるので、試験工数が単純に倍になってしまうんですよね。 もちろん、Flutterの描画エンジンはOSへの依存が少ないので「片方のOSで確認すれば十分」とも言えるんですが、そこはまだ実務で踏み切れていないのが現状です。
永井:
なるほど。セッションでも触れていた、実装以外の工程における理想と現実のギャップですね。若宮さんのところはどうですか?
若宮:
似たような課題ありますね。Flutterでは Platform.isAndroid
とかで分岐せざるを得ないところも出てきて、共通化が想定より進まないこともあります。特にQRコードリーダーまわりでCameraXに変えたらChromebookで動かなくて、Camera1に戻す…みたいな地味にキツい話もありました。
永井:
本来Android単独の問題が、マルチプラットフォームゆえにiOSにも影響したということですね。
若宮:
そうなんです。今はiOS・Androidに詳しいメンバーがいて、なんとかなっている状態です。全員がFlutterしか書けないチームだったら、たぶん詰んでました。
桐山:
PlatformViewまわりもまだ不安定ですね。たとえばFlutterEngineGroupで複数のエンジンを起動して、WebViewやGoogleMapなどPlatformViewを利用したコンポーネントを表示しようとすると、クラッシュすることがあったりして。
永井:
そのへん、Add-to-app構成から始めた『じゃらんnet』ならではのハマりポイントですね。Flutterとネイティブの画面を行き来するハイブリッドな構成だからこその。
桐山:
はい。深いネイティブの知識が求められる場面はまだまだ多いです。
永井:
マルチプラットフォーム化したからこそ、トラブルシューティングにおいてより深いネイティブの知識が求められるということがありそうですね。
桐山:
そうですね。我々も重視しているのはFlutter経験よりもネイティブ経験のほうです。ビルドやトラブルシューティングの場面で頼りになるのは結局そっち。
永井:
宣言的UIの間での親和性はありますもんね。飲食もKotlin Multiplatform(KMP)を導入したばかりの頃はネイティブの深い知識が求められる場面が多くありました。
2. マルチプラットフォーム化すべきでないプロダクト特性
永井:
では次に、「マルチプラットフォーム化しないほうがいいな」と思うプロダクト特性について聞かせてください。若宮さんからお願いします。
若宮:
Bluetoothとかセンサー系、あとはキーボードのカスタマイズ系ですね。こういった低レイヤー技術を使うアプリは、マルチプラットフォームと相性が悪いです。理由は3つあります。
1つは、API仕様の違い。たとえばBluetoothで通信するとき、AndroidとiOSでイベントの流れも使える機能も全然違います。
2つ目は、ベンダー依存の挙動差。Android端末は特にメーカーごとにBluetoothの動作が微妙に違ったりするんですよ。
3つ目は、調整の難しさです。たとえば、近いデバイス同士でオフライン通信したい、といったユースケースを想像すると、ネイティブであっても結構骨が折れる。それをFlutterでDart側から全部扱おうとすると、デバイス検出や通知レベルの制御、セキュリティ制約に対応しきれないことが多いです。
桐山:
確かにマルチプラットフォーム化の効果は薄くなりそうですが、ネイティブであっても分岐は発生するものですよね?
永井:
確かに。ただ、デバッグの難しさは明確に失っているものになるかも。うまくいかない時に「何が原因か」を切り分ける対象範囲が増えてしまう。IDE(統合開発環境)の進歩で解決する部分もありそうですが。
若宮:
そうなんです。「Flutterの問題なのか、Dartの実装なのか、それともOSレベルなのか?」が見えにくくて。最終的にはネイティブ側を触らないとどうしようもない、ってケースが多いですね。あと、iOS特有のUI(キーボードのサジェストバーとか)をカスタマイズしたい場合、Flutterでは現状実現が難しいと思っています。ネイティブのExtension APIがFlutterに公開されてないこともありますし。
永井:
そこが事業におけるコア体験と直結してるなら、最初からネイティブ選んだ方が良いですよね。
若宮:
そういう意味でも、低レイヤーの処理やプラットフォーム依存の要件が多いアプリでは、マルチプラットフォームを採用するメリットが薄いです。「共通化できる層が薄い」=「やっても効果が出づらい」っていう構造になっちゃう。
永井:
でも逆に、特殊な要件がなければFlutterでもCompose Multiplatformでもけっこういける。だから「やらない理由」も冷静に見極めたほうが良さそうですね。
3. マルチプラットフォーム化の今後の展望
永井:
では最後に、それぞれの今後の展望を話して終わりにしましょう。まずは飲食領域からいきますね。
Compose Multiplatformを導入しつつ、KotlinベースでiOS/Androidの共通化を進めています。ただ、Webとの統合は正直厳しい。SEO要件を考えると、WASM前提の構成では勝負できません。Kotlin HTML DSLなどを活用したテンプレート生成のような別アプローチを模索しています。
桐山:
旅行領域でもWeb統合は現実的ではないですね。Flutterで主要動線の置き換えを進めていて、改修頻度の低い画面はそのまま残すという戦略を取っています。Flutterを中心とした体制を強化しながら、ネイティブ側で発生するトラブルにも踏み込んで対応できるようなスキルセットをチーム内に備えていこうとしています。
若宮:
まなび領域(進路)ではFlutterでのアプリ開発がメインになっていて、Flutterアプリのエンハンスと既存ネイティブアプリのリプレイスを並行して行っています。チーム人数は据え置きのまま、2ライン開発を実現できている状態ですね。
永井:
それがまさに、マルチプラットフォーム化の大きな利点ですよね。柔軟性とスピードの両立。
若宮:
そうですね。Flutterなら1コードで2プラットフォーム分面倒見られるので、チームの対応範囲が拡大しています。これまで改善の手が入れられなかったアプリに、増員なしで対応できる余地が生まれています。
桐山:
でも、その分Flutterだけじゃなくネイティブの理解も求められるので、採用や育成戦略は重要になりますね。
永井:
そうですね。将来的には、WebもサーバーもiOS・Androidもある程度触れる“再定義されたフルスタックエンジニア”が活躍する時代になるかもしれません。生成AIの補助もありつつ、マルチなドメイン知識を持つことで、より高速にサービスを回す体制が作れると思います。
おわりに
永井:
今回は、マルチプラットフォーム化の「実情」を率直に語ってみました。理想通りにはいかないことも多いですが、向き合い方次第で得られるものも大きいと思います。FlutterでもCompose Multiplatformでも、「どう使うか」「どう組織に浸透させるか」が問われるフェーズに入っているのかもしれません。
桐山・若宮:
ありがとうございました!