第76回ブログ|Flutter 3.47 は「モジュラー化」の号砲 — Material/Cupertino独立、Wasmデフォルト化、Apple 27世代対応から読むFlutterの狙い

Flutter 3.47 モジュラー化と次世代実行基盤

はじめて読む方へ: この記事では、Flutter 3.47 の変更点を「単なる新機能」ではなく、Flutter がどの方向へ進もうとしているのかという視点で整理します。細かいAPI名をすべて覚える必要はありません。まずは Material/Cupertino の独立Impeller と Wasm による実行基盤の刷新Apple 27世代対応に伴う移行作業 の3つを押さえてください。

対象読者: Flutterを業務で使っている / 導入を検討しているエンジニア

元記事: What's new in Flutter 3.47(2026年8月12日公開・Emma Twersky)


0. 3行まとめ

そして、これら3つはバラバラの機能追加ではなく、「コアを薄くし、周辺を差し替え可能にする」という一本の設計思想でつながっている、というのがこの記事の主題です。


1. 前提: そもそもFlutterとは何か、なぜ今この話が重要なのか

Flutter は Google が開発するオープンソースのUIフレームワークです。Dart という言語で書いた単一のコードベースから、

を生成できます。「Write once, run anywhere」を謳うフレームワークは過去にいくつもありましたが、Flutterの特徴はOSのUI部品を借りてくるのではなく、自前の描画エンジンで画面を全部描くという割り切りにあります。だからこそ全プラットフォームでピクセル単位で同じ見た目を出せる一方で、「描画エンジン」と「デザイン部品」がフレームワークの心臓部に居座る構造になっていました。

Flutter 3.47 は、まさにその心臓部の構造そのものに手を入れるリリースです。個別の便利ウィジェットが増えた、という話ではありません。ここが今回いちばん押さえるべきポイントです。

用語の下地(この記事で繰り返し出てくるもの)

用語意味
MaterialGoogle発のデザインシステム。Androidらしい見た目のウィジェット群
CupertinoAppleのヒューマンインターフェースに寄せたデザインシステム。iOSらしい見た目のウィジェット群
pub.devDart/Flutter の公式パッケージレジストリ(npm や PyPI に相当)
SkiaFlutterが長年使ってきた2Dグラフィックスライブラリ。Chromeなどでも使われている
ImpellerSkiaを置き換えるために一から作られたFlutterの次世代レンダリングエンジン
Wasm(WebAssembly)ブラウザ上でネイティブに近い速度で動くバイナリ形式。JavaScriptより高速な実行が期待できる

2. 目玉その1: Material と Cupertino がSDKから独立した

何が起きたのか

これまで Material と Cupertino は、FlutterのコアSDKに直接同梱されていました。import 'package:flutter/material.dart'; と書けば使える、あの状態です。

公式の説明によれば、この「同梱」構造こそが開発速度のボトルネックでした。デザインライブラリの改善がコアSDKのリリースサイクルに縛られ、外部からのコントリビュートもしづらかったからです。

3.47 では、これらが独立パッケージとして pub.dev 上で 1.0 に到達しました。

何が嬉しいのか(実務目線)

公式が挙げているメリットは3点です。

  1. FlutterのSDKバージョンを上げずに、最新のMaterial/Cupertinoスタイルだけを取り込める。

これは業務システムを長期保守する立場だと非常に大きい。「デザインの新コンポーネントが欲しいだけなのに、SDKを丸ごと上げてビルドが全部壊れる」という事故を回避できます。

  1. 修正やコントリビュートが速く回る。

独立パッケージ側は週次リリースを予定しており、四半期ごとのSDKリリースを待つ必要がなくなります。バグ修正の到達が単純に速くなる。

  1. 将来的に「スタイル中立なコアウィジェットカタログ」への地ならしになる。

独自デザインシステムを構築しやすくなる、という長期の布石です。

3点目が、後述する「Flutterの狙い」に直結します。

移行方法

自動移行ツールが用意されています。

dart fix --apply --code=migrate_design_widgets

これで package:flutter/material.dart / package:flutter/cupertino.dart の import が新パッケージ向けに書き換わります。

注意(公式に明記されている既知の初期バグ)

移行ツールが pubspec.yaml の更新に失敗することがあります。その場合は手動で flutter pub add material_ui(Cupertinoを使うなら cupertino_ui も)を実行してから、もう一度 dart fix --apply を回してください。

依存パッケージがまだ移行していない場合の橋渡し

現実の案件では「自分のコードは移行できるが、依存している3rdパーティのパッケージが旧importのまま」という状態が必ず発生します。ここに対して MaterialUiCompatibilityBridge という互換ブリッジが提供されています。

import 'package:material_ui/material_ui.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF6750A4)),
      ),
      builder: (BuildContext context, Widget? child) {
        return MaterialUiCompatibilityBridge(child: child!);
      },
      home: const HomeScreen(),
    );
  }
}

アプリ側だけ先に移行し、エコシステムの追随を待てる設計になっています。「全部揃うまで待つ」ではなく「先に動ける」ようにしたのは実務的にありがたい判断です。

ローカライゼーションも分離された

ローカライゼーション(多言語対応) の設定も変わります。従来 flutter_localizations にまとまっていた Material/Cupertino ウィジェット用の翻訳文字列とデリゲート(「このロケールの文言セットを供給する係」のオブジェクト)が、それぞれのパッケージ側に移りました。

Before:

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter/material.dart';

localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
  GlobalCupertinoLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
],

After:

import 'package:material_ui/material_ui.dart';

localizationsDelegates: GlobalMaterialLocalizations.delegates,

GlobalMaterialLocalizations.delegates を1行指定するだけで、Cupertino と Widgets のデリゲートも一緒に含まれるようになりました。地味ですが、毎回コピペしていた定型句が消えるのは良い変更です。

タイムライン(ここが一番重要)

また、公式は「移行を安全にするため2026年4月時点で Material/Cupertino ライブラリへのコントリビュートを凍結していた」と述べています。つまり material_ui / cupertino_ui の中身は今使っているものと同一であり、移行してもウィジェットの挙動が変わるわけではない。凍結はこのリリースで解除され、今後は新パッケージ側で週次に修正・機能が流れてくることになります。


3. 目玉その2: Apple 27世代(Xcode 27 / iOS 27 / macOS 27)への備え

この秋にAppleの次期OSが来るのに合わせ、地ならしが入りました。iOS/macOSアプリを配信している人はここが一番、実害に直結するセクションです。

最低サポートOSの引き上げ

プラットフォーム従来の最低3.47以降の最低
iOS1315
macOS10.1512

Xcode 27 をサポートするための引き上げです。医療機関や自治体など、端末更新サイクルが長い現場に納品している場合は、顧客の端末OSバージョン分布を先に確認する必要があります。

UIScene ライフサイクル対応が必須化

UIScene とは、iOS 13で導入された「1つのアプリが複数のウィンドウ(シーン)を持てる」ことを前提としたアプリのライフサイクル管理の仕組みです。従来の AppDelegate 中心のライフサイクルに代わるものとして用意されていました。

iOS 27 SDK では、この UIScene ライフサイクルが UIKitベースの全アプリで必須になります。公式の記述は明快で、Xcode 27 でビルドされた UIScene 非対応アプリは起動時に失敗するとされています。

該当しそうな心当たりがあるなら、Appleのベータ版が出ている今のうちに検証しておくべきです。公式も「初日に驚かないよう、今のうちにAppleのベータでテストを」と推奨しています。移行手順は UIScene/Delegate Adoption Guide にあります。

Intel Mac のフェードアウト

AppleのApple Silicon移行に合わせ、FlutterもIntel Macサポートを段階的に終了していきます。

ARM64のみのmacOSアプリを今すぐ作ることもできます。

flutter config --enable-macos-arm64-only

ビルドマシンにIntel Macを残している現場は、計画的な入れ替えを検討する時期です。

Swift Package Manager(SwiftPM)移行の進捗

CocoaPods は長らくiOS/macOS開発で使われてきた依存関係管理ツール、Swift Package Manager(SwiftPM) はApple公式の後継にあたる仕組みです。Flutterはこの移行を進めています。

自作プラグインを公開している場合は、移行ガイドを確認しておきましょう。なお本リリースではコミュニティコントリビュータによってSwiftPMの不要なスキームをビルド初期に除外する改善が入り、ビルド時間も最適化されています。


4. 目玉その3: Wasmデフォルト化への航路

Flutter Web の実行形式を WebAssembly(Wasm)をデフォルトにする方向で作業が進んでいます。狙いは明快で、ブラウザ上でネイティブに近いパフォーマンスを出すことです。

今日から試せます。

flutter build web --release --wasm

移行の前提条件(ここを見落とすとハマる)

Wasm を使うには、JS interop(DartとJavaScriptの相互運用)を新しい package:web に移行しておく必要があります。 従来の dart:html ライブラリはサポートされません

ただし公式は「プロジェクトの依存パッケージを最新に上げるだけで、この手のレガシーinterop問題は自動的に解消することが多い」とも書いています。まず flutter pub upgrade を回してから --wasm でビルドを試すのが早い、ということです。

大規模Webアプリ向けの遅延ロード(実験的)

遅延ロード(deferred loading) は、アプリ全体を最初に読み込まず、必要になった時点でモジュールを分割ロードする仕組みです。初期表示を速くするための古典的かつ強力な手法ですが、これが Wasm でも使えるようになりました(mainチャンネルでフラグ付きの実験的サポート)。

flutter build web --release --wasm --enable-wasm-deferred-loading

管理画面やダッシュボードのような画面数の多い業務系Webアプリでは、初期ロード時間が採用可否を左右することが多いので、これは実務的に重要な一手です。


5. 目玉その4: Impeller がデスクトップでデフォルトに

Impeller とは何か

Impeller は、Skia を置き換えるためにゼロから作られたFlutterの次世代レンダリングエンジンです。最大の特徴はシェーダのコンパイル戦略にあります。

シェーダとはGPU上で走る小さな描画プログラムのこと。従来のSkiaベースの構成では、これを実行時に動的にコンパイルしていました。その結果、あるアニメーションを初めて再生した瞬間だけカクつく現象 —— シェーダコンパイルジャンク(shader compilation jank) が発生していました。Flutterに触れたことがある人なら、「初回だけ妙に引っかかる」あの挙動に心当たりがあるはずです。

Impeller は Metal(macOS)や Vulkan(Windows / Linux)といったモダンなハードウェアAPIを直接ターゲットにし、シェーダを固定セットとしてビルド時にコンパイルします。結果として、最初の1フレーム目から一貫して滑らかなトランジションが得られます。

3.47 では、これが macOS / Windows / Linux でデフォルトになりました。

一時的な無効化(あくまで緊急避難)

プラットフォーム無効化方法
macOSInfo.plistFLTEnableImpellerfalse
Windowsmain.cppproject.set_impeller_switch(flutter::ImpellerSwitch::Disabled)
Linuxmy_application.ccfl_dart_project_set_enable_impeller(project, FALSE)

ただしこのフォールバックは将来のリリースで削除されると明言されています。Skiaに戻さざるを得なかった場合は、回避策として使うのではなくバグ報告を上げてほしい、というのが公式のスタンスです。ここは「移行猶予」ではなく「移行完了までの最終区間」と読むべきでしょう。

あわせて macOSでは Wide Gamut Color(広色域)がデフォルトで有効になり、対応ハードウェア上でより豊かで正確な色表現が得られます。

デスクトップまわりのその他の強化

Impellerだけでなく、デスクトップは今回まとまった強化が入っています。Flutterがデスクトップを本気で一級市民として扱い始めたと読める内容です。

マルチウィンドウ(実験的) — Canonical(Ubuntuの開発元)との協業で進行中。

flavors がデスクトップでも使えるようにflavor(フレーバー) とは、同一コードベースから「開発版 / 検証版 / 本番版」「顧客A向け / 顧客B向け」といった変種ビルドを作る仕組みです。これまでモバイル中心だったものが Windows / Linux でもサポートされました。

flutter:
  assets:
    - path: assets/flavor_a/images
      flavors:
        - flavor_a
    - path: assets/flavor_b/images
      flavors:
        - flavor_c
flutter build windows --flavor flavor_a
flutter build linux --flavor flavor_a

受託開発で同一アプリを顧客ごとにブランディングして納品するようなケースでは、これは地味どころか本命級の機能です。

デスクトップの文字が鮮明に — デスクトップのディスプレイはモバイルに比べて画素密度が低い一方、GPUの演算能力には余裕があります。この特性を活かし、Impeller使用時に SDF(Signed Distance Function)レンダリングを採用しました。SDFは「輪郭までの距離」を関数として持つことで、拡大縮小しても輪郭が滑らかに保たれる描画手法です。結果として、macOS / Linux / Windows でより鮮明なテキストと綺麗なベクター曲線が得られます。


6. 開発体験まわり: Widget Preview の stable 化と GenUI

Widget Preview が stable に

Widget Preview は、アプリ全体をビルド・起動することなく、個々のUIコンポーネントだけを即座に描画・確認・反復できる機能です。今回 stable になりました。

GenUI の進展

GenUI(Generative UI) は、AIエージェントがコンテンツを生成するだけでなく、それをどう表示しどう操作可能にするかまで決めるというUXパターンです。Flutterではこれを genui パッケージで実装します。

その下敷きになっているのが A2UI(Agent-to-UI) —— エージェントとクライアント(レンダラ)がUIの構成と状態を協調して決めるためのオープンプロトコルです。噛み砕くと、LLMが「UIそのもの」をJSONで吐き、Flutter側は開発者が許可したウィジェットカタログの範囲内でそれを実際のウィジェットとして描画する、という仕組みになります。コード生成ではなく、実ウィジェットの実行時合成である点がポイントです。

3.47のタイミングで genui0.10.0 がリリースされ、

が入りました。後者は体感速度に効く実務的な改善です。

補足として、A2UIとgenuiは執筆時点でまだ活発に仕様が動いている領域です(プロトコルはv0.9系、genuiパッケージもアルファ扱いの記述が残っています)。今すぐ本番の中核に据えるより、プロトタイプで検証する段階と捉えるのが妥当でしょう。


7. その他のプラットフォーム改善(要点のみ)

Android

iOS / macOS

(このあたりは地味ですが、証明書まわりのトラブルシュートに費やす時間を考えると効きます)

デスクトップ / エンジン / フレームワーク


8. 考察: Flutterは何を狙っているのか

ここからは、3.47の内容とFlutterの2026年ロードマップを突き合わせた筆者の読みです。

軸1: 「厚いフレームワーク」から「薄いコア + 交換可能な層」へ

これが最大の変化だと考えています。

Flutterの2026年ロードマップには、Material/Cupertinoの分離と並んで、エンジンやCLIの拡張性を高め、新しいプラットフォームへの対応を "out-of-tree"(コアリポジトリの外)で書けるようにするという方針が明記されています。今回のデザインシステム独立は、その第一歩にすぎません。

構造を整理するとこうなります。

【従来】
┌─────────────────────────────┐
│  Flutter SDK(一枚岩)        │
│  ┌───────┬───────┬────────┐ │
│  │Material│Cupertino│ Widgets│ │  ← デザインが心臓部に同居
│  ├────────┴────────┴────────┤ │
│  │  Engine(Skia)           │ │
│  └───────────────────────────┘ │
└─────────────────────────────┘

【向かっている先】
        ┌──────────┐ ┌───────────┐ ┌──────────────┐
        │material_ui│ │cupertino_ui│ │ 独自デザイン系 │  ← pub.devで週次に進化
        └─────┬────┘ └─────┬─────┘ └──────┬───────┘
              └────────────┼───────────────┘
        ┌──────────────────▼───────────────────┐
        │ スタイル中立なコアウィジェットカタログ    │
        ├──────────────────────────────────────┤
        │ Engine(Impeller)/ out-of-tree 拡張   │
        └──────────────────────────────────────┘

公式が「style-neutral(スタイル中立)なコアウィジェットカタログへの地ならし」と書いているのは、この図の下半分を指しています。つまり Flutter のコアは最終的に、レイアウト・描画・ジェスチャー・プラットフォーム連携に専念し、見た目は完全に差し替え可能なレイヤに追い出す方向を目指している。

なぜそれが必要なのか。 Flutterはもう「Androidアプリを作るためのGoogleのツール」ではなくなったからです。デスクトップ、Web、車載、TVと展開先が広がるほど、「Material が標準」という前提は足枷になります。Windowsアプリを作るのにMaterialのデフォルトと戦う、という状況は不健全です。デザインシステムを外に出すことは、フレームワークが特定のデザイン言語にハードコードされている状態からの脱却であり、成熟したフレームワークが必ず通る道でもあります。

軸2: レンダリングパイプラインの一本化を完了させにいく

Impellerのデスクトップデフォルト化と、フォールバック(Skiaへの退避)を将来削除すると明言したこと。この2つはセットで読むべきです。

Flutterは長年、SkiaとImpellerという2つのレンダリングパスを並走させてきました。並走は互換性の保険になる一方、テストマトリクスは倍になり、パフォーマンス最適化は分散します。「バグを報告してほしい、回避策として使い続けないでほしい」という書き方は、保険期間の終了予告です。

これはFlutterが性能面での言い訳を潰しにきているということでもあります。「初回アニメーションがカクつく」はFlutter批判の定番でしたが、それを構造的に消しにかかっている。デスクトップでのSDFレンダリング採用(=デスクトップは画素密度が低い代わりにGPU演算に余裕がある、というプラットフォーム特性への最適化)も、「全プラットフォーム同一」から「プラットフォーム特性に合わせた最適化」へという成熟のサインです。

軸3: Webを「妥協先」から「一級の配信先」へ

Flutter Web はこれまで、正直に言えば「動くには動く」というポジションでした。JavaScriptにコンパイルされる以上、実行速度には天井がある。

Wasmをデフォルトにするという意思決定は、この天井を外しにいくものです。ロードマップにも「ネイティブ品質の体験と性能を届けるため、WebではWasmをデフォルトにする意図がある」と明記されています。加えて今回のWasmでの遅延ロード実験は、「小さなデモは速いが実アプリは重い」という次の壁への対処です。

実務的な含意は明確です。「モバイルアプリを作ったついでにWebにも出す」から、「業務Webアプリの第一候補としてFlutterを検討する」への移行が視野に入ってきます。ただし前述の通り、dart:html 依存の古いコードを抱えている場合は移行が前提条件になります。まだWasmビルドを試していないなら、いま試すべきタイミングです。「デフォルトになってから慌てる」のが最悪のパターンなので。

軸4: AIエージェント時代のUIレイヤを取りにいく

GenUI / A2UI の位置づけは、他の3軸と比べると投機的です。しかし方向性としては一貫しています。

従来のアプリは、開発者がビルド時にウィジェットツリーを固定していました。GenUIはそれを覆し、エージェントに「使ってよいウィジェットのカタログ」と「目的」を渡すと、実行時に画面が組み上がるという発想です。アプリストアの審査を待たずに画面が変わる、と言えばインパクトが伝わるでしょうか。

ここでFlutterが持つ構造的な強みは、全プラットフォームで同一のウィジェット体系を持っていることです。「エージェントが吐いたUI記述を、iOSでもAndroidでもWebでもデスクトップでも同じように描画できるレンダラ」を提供できるフレームワークは、そう多くありません。軸1のデザインシステム分離(=ウィジェットカタログを差し替え可能にする)とも綺麗に噛み合います。

一方で、ここは冷静さも必要です。プロトコルはまだ0.9系で、SDKもアルファ。「UIをモデルに任せる」ことの品質保証をどうするかという問題は未解決です。業務システム、特に医療や金融のように画面の挙動が決定的であることが要件になる領域では、当面は「エージェントが生成した画面が想定外の状態を作らないこと」を保証する設計が別途必要になります。触っておく価値は高いが、任せきりにするのはまだ早い、というのが現時点の妥当な距離感でしょう。

まとめると

Flutter 3.47 は、「多機能なフレームワーク」から「堅牢で薄い基盤 + 交換可能なエコシステム」への転換点です。派手な新ウィジェットはありませんが、構造を作り替えるリリースは、たいていの場合その後の数年を決めます。

そして忘れてはいけないのは、この転換が移行コストとして開発者に降りてくることです。11月の非推奨化までに、手を打つ時間はあまり長くありません。


9. 実務チェックリスト

3.47 を受けて、いま確認すべきことを優先度順に整理します。

優先度: 高(この秋までに)

優先度: 中(半年以内に)

優先度: 低(余力があれば)


10. 参考リンク


*本記事は Flutter 3.47 の公式リリースブログ(2026年8月12日公開)の内容をもとに構成しています。「考察」セクションは公式の記述と2026年ロードマップを踏まえた筆者の解釈であり、公式見解ではありません。*