バックエンドエンジニアがFlutter領域に越境してみて
導入
昨今、Claude Code や Cursor のような生成 AI ツールが一気に普及し、コードリーディングや実装の難易度は以前と比べてだいぶ下がったと感じています。
自分の得意領域であるバックエンドだけでなく、モバイルアプリや Web フロントエンドのような、これまでちょっと遠いなと感じていた領域にも、AI に手を引いてもらいながら踏み込めるようになりました。
前置きというか前提として自分は現在バックエンドエンジニアとして働いていますが、実は新卒の会社や副業・インターンの現場で、Flutter を使った開発を少し経験したことがあります。
とはいえ、開発していた時から期間も空いていたので、文法や Widget の名前をなんとなく覚えている程度の状態からの再スタートでした。ただ今回の記事では、Flutter 経験があったから楽でしたと強調したいわけではありません。
生成 AI と、「越境を歓迎する組織の文化」があると、専門外の領域にもここまで踏み込めるのか
という点を中心に書いていきたいと思います。
SODA では、Flutter チーム側が「越境される側の文化づくり」を丁寧に進めてくれています。
弊社アプリチームリードのimajo さんの記事を参考 ↓
そんな環境の中で、半期ほどアプリエンジニアの皆さんに補助されながらFlutter領域に越境させていただいたので、そのときの知見や感想などを書いていこうと思います。
本記事では、
- バックエンドエンジニアとして Flutter 領域に越境して「できたこと」
- 実際にやってみて「難しいな」と感じたポイント
- AI 時代の越境のしやすさ・難しさ
- Flutter チームが整えてくれた「土壌」のありがたさ
あたりを、あくまで一開発者の視点からまとめてみます。
できたこと
小さめの機能や改修なら一人で完結できるようになった
今回、ある程度まとまった期間 Flutter を触ってみて、一番分かりやすい変化は、
小さめの機能や改修なら、一人で最後まで届けられるようになった
という点です。
具体的には、次のようなタスクを自走で進められるようになりました。
- 既存画面の文言・スタイル調整
- ボタンやラベルといったコンポーネントの追加やプロパティ変更
- 既存の API クライアントを利用したデータ取得・表示
- 追加された機能に合わせた新規画面の作成と画面遷移の実装
Dart の文法や Widget の基本はうっすら覚えている状態からの再スタートでしたが、
コードベースを読み進めながら、生成 AI に補助してもらいつつ、だんだんとこのプロジェクトではこう書くというパターンが見えてきました。
AI には、たとえば次のような使い方をしました。
- 長めの Widget ツリーの意図や役割を要約してもらう
- 似たような画面や実装例をコードベース内から探す手助けをしてもらう
- エラー文言の意味や解決策の候補を出してもらう
ただし、AI にコードそのものを丸投げするのではなく、すでにプロジェクトに存在する書き方・パターンから外れないか、を自分でチェックする意識は常に持つようにしました。
チーム内でも小さな変更であればアプリエンジニアの力を借りずに動作確認をしながらPRを出せるようにもなりました(PRレビューはお願いしているので力は借りている)。
特に問い合わせや不具合があった際に、自分たちで一次調査をできるようになったのも大きいかなと個人的には感じています。
「越境そのもの」は思っていたより現実的だった
もう一つ感じたのは、
「専門がバックエンドだから、アプリはまったく分からない」という状態ではなかった
ということです。
- 非同期処理(async/await や Future)の考え方
- API の I/O をどう型で表現するか
- エラーハンドリングやリトライの考え方
などは、バックエンドで普段から考えていることとかなり共通していました。
文法やライブラリは違っても、どういう責務の単位でコードを分けていくか、という設計の感覚は、かなりそのまま持ち込めると感じました。
ここで効いたのは、過去に Flutter を触った経験そのものというよりも、日頃からバックエンド側で設計や運用を考えていることでした。
「この API のレスポンスはこういう構造になっていそう」「ここはバックエンド側の制約上この挙動になるはず」といった見立てができるのは、越境する上で大きな武器になるなと感じました。
難しいなと感じたこと
もちろん、やってみて「ここは難しいな」と感じた部分もはっきりありました。
パッションとプロダクト志向はやっぱり必要
AI のおかげで、「とりあえず動くコード」を書くことの難易度は下がりました。
一方で、「ちゃんと気持ちよく使える UI に仕上げる」ことの難易度は、あまり下がっていないかもと感じました。
- スクロール時のアニメーションの自然さ
- 画面遷移のときの違和感のなさ
- ローディング・エラー時の表示の細かな配慮
このあたりは、プロダクトそのものへの興味や「もっと良くできるはず」というこだわりがないと、AI の提案だけではなかなか到達できません。
コードとしては正しくても、「なんか使っていて気持ちよくない」という状態から先に進めるかどうかは、自分のパッション次第だと感じました。
「プロンプトを頑張ればなんとかなる」には限界がある
もう一つは、「プロンプトの質を上げれば解決する」という期待はあまりできないということでした。
- StatefulWidget / StatelessWidget の使い分け
- どのレイヤーで状態を持つか
- Riverpod などの状態管理をどの粒度で使うか
- 画面遷移(Navigator やルート設計)の方針
こういった「チームとしての設計の流儀」を理解していない状態で AI に聞くと、
確かに動くコードは出てくるものの、そのプロジェクトらしさからは外れてしまうことが多かったです。
例えば、旧アーキテクチャやパターンが多くあり、新しく書くコードではそのパターンを踏襲しない、というような場合、プロンプトで明言しない限り多く残っている方を参考にして成果物を出されることが多かったような印象でした。ここの前提を知らないととりあえず動くのは書けるけど負債を量産しているのであまり良い状態とは言えなそうでした。
逆に、「この画面の責務はここまで」「状態はこの Widget の外に出したい」「このデザインシステムのボタンを使いたい」といった前提を自分で整理したうえで AI に相談すると、提案の精度はかなり上がりました。
ここから分かったのは、AI に渡す前提を整理する力そのものが、越境で一番鍛えられるということかもしれません。
得た知見
文法の違いより、「どのレイヤーが何を担当するか」の違いが重要
バックエンドや Web フロントの経験があると、Dart の文法そのものは数日で慣れてきます。
実際、「文法の違い」は越境の大きな壁ではありませんでした。
一方で、Flutter 特有の「責務の分け方」には慣れが必要でした。
- UI レイヤー(Widget ツリー)がどこまでやるのか
- ビジネスロジックや状態管理をどこへ逃がすのか
- Riverpod などを使う場合の粒度や構成
これらは、バックエンドのレイヤードアーキテクチャや DDD 的な考え方と似ている部分もありつつ、
「フレームワークが前提としている世界観」が違う分だけ、最初は戸惑います。
ただ、一度「このプロジェクトではこう分ける」というルールが掴めてくると、
バックエンド側の設計経験がそのまま活きてくる感覚もありました。
余談:React / Vue の宣言的 UI 経験はかなり効いた
余談ですが、個人的にかなり効いたと感じたのが React や Vue の宣言的 UI の経験でした。
- 「状態が変われば UI が再描画される」という発想
- コンポーネントを小さく分割して組み合わせていく感覚
- props / state(あるいは ref)の流れを意識する癖
このあたりは、Flutter でも本質的には同じです。
特に、Riverpod の hooks まわりは React Hooks にかなり近いインターフェースで、
Recoil などモダンな状態管理のエッセンスを取り入れていることもあり、「あ、これは React でやっていたアレだな」と感じる場面が多くありました。
なので、フロントエンド領域においては、
言語やフレームワークに強く依存するというより、
「現代的な宣言的 UI のエッセンス」を押さえておくと潰しが効く
と感じる部分が多いなと思いました。
React / Vue / Flutter と複数のスタックをまたいでみると、
それぞれの細かい作法は違いつつも、「状態をどう表現し、どう UI に反映するか」という本質部分はかなり共通していることが分かります。
むしろ複数を触ることで、「ここは React の影響が強そう」「ここはモバイルアプリならではの考え方だな」と、多角的な理解ができるのもおもしろいところでした。
アプリ特有の前提・単語を押さえておくと、理解コストが一気に下がる
アプリ開発には、Web とは違う前提や用語がいろいろあります。
- OS やストアまわりの話(Bundle ID / 実機ビルド など)
- 画面遷移パターン(モーダル / フルスクリーン / プッシュ遷移 / タブ構成 など)
- レイアウト・レスポンシブ対応(SafeArea, MediaQuery, デバイスごとの比率感覚 など)
これらをまったく知らない状態でコードだけ読むと、「なぜこういう実装になっているのか」がいつまでも腹落ちしない感覚がありました。
Flutter チームが勉強会やドキュメントでこの辺りを整理してくれていたおかげで、言葉の壁で止まる時間がかなり減ったのは大きかったです。
デザインシステムと Widget 群は、越境を支える強力なレール
SODA の Flutter チームが整えてくれているデザインシステムや共通 Widget 群は、越境する側にとって本当にありがたいレールでした。
- Figma 上のコンポーネントと Flutter の Widget が対応している
- ボタンやテキストのスタイルが統一されている
- 細かな余白やアクセシビリティ面の工夫が、コンポーネント側に吸収されている
その結果、レイアウトの正解をゼロから探すのではなく、
用意されている部品の組み合わせ方に集中することができました。
真に越境していくには、もっと深いところに踏み込む必要がある
AI とチームの土壌のおかげで、「タスクをこなす」という意味での越境はかなりやりやすくなっています。
とはいえ、「Flutter エンジニアとして自走する」というレベルに到達するには、まだまだやることが多いとも感じました。
- 状態管理やアーキテクチャの選定理由を説明できること
- パフォーマンス問題を自分で切り分け、計測・改善していくこと
- 新しいフローや機能の UI/UX をゼロから設計し提案すること
これらは、AI だけではどうにもならない「経験と試行錯誤の領域」だと感じました。
ただ、その入り口までのハードルが大きく下がったのは間違いなく、ここから先は自分がどこまで踏み込みたいか次第だとも感じています。
まとめ
今回、バックエンドエンジニアである自分が Flutter 領域へ越境してみて強く感じたのは、
越境のしやすさは、個人のスキルだけでなく、
「越境される側がどれだけ土壌を整えてくれているか」もかなり効いてくる
ということです。
- 整った環境構築手順とアーキテクチャのドキュメント
- デザインシステムや共通コンポーネント
- 勉強会・コードレビュー・ペアプロといった学びの場
- 「分からないことを聞いていい」空気感
Flutter チームがこういった土壌を丁寧に整えてくれていたからこそ、
自分のようなバックエンドエンジニアでも、アプリ側の機能開発に継続的に参加することができました。
補足
一方で、本記事を書くにあたり参考にした以下の記事から
「越境はそれ自体を目的にしてはいけない」という視点も強く意識するようになりました。
参考記事にある通り、本来、越境なんてしなくても、それぞれの専門性だけで組織やプロダクトが回るのが一番きれいな姿だと思います。
大事なのは「越境すること」ではなく、あくまで プロダクトを良くする/課題を解決するために動いた結果として、たまたま越境していた という状態だと思います。
ただ、スタートアップやベンチャーのように制約が多い現場では、
「ここで誰かが一歩はみ出して動けると、明らかに良くなるのにな」
という瞬間が結構あると思います。
そのときに効いてくるのが、
- 越境しやすい 土壌(ドキュメント・設計・文化)があること
- いざというときに踏み出せる 個人の準備と経験があること
の 2 つだともいます。
土壌がなければ「自分がやる」という選択肢は最初から上がってこないし、準備がなければ「越境しないでなんとかする」方向に寄っていってしまいます。
今回、自分は Flutter チームが整えてくれた土壌に思いきり乗らせてもらいました。
今度は自分が「越境される側」として、バックエンド領域に興味を持ってくれる Flutter / Web フロントのメンバーを支える番だと感じています。
- バックエンドの環境構築を簡単にする
- ドメインやデータモデルをキャッチアップしやすい資料を用意する
- AI とレビューを組み合わせて、安心してコードを書いてもらえる場をつくる
「越境」はゴールではない、けれどいざ必要になったときに いつでも越境できる土壌と能力を備えておくこと は、これからのエンジニアリング組織にとって大きな武器になるのではと思います。
SODA には、越境を強制する文化はありませんが、「やってみたい」という声を歓迎し、後押ししてくれる環境があります。
もしこの記事を読んで、少しでも「こういうチームで働いてみたい」と感じていただけたなら、ぜひカジュアル面談などでお話しできると嬉しいです。
株式会社SODAの開発組織がお届けするZenn Publicationです。 是非Entrance Bookもご覧ください! → recruit.soda-inc.jp/engineer
Discussion