はじめて読む方へ: この記事では、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)
material_ui / cupertino_ui として pub.dev で 1.0 に到達した。今回はオプトイン(任意)だが、コア同梱版は2026年11月の秋のstableリリースで正式に非推奨(deprecated)になる予定。UIScene ライフサイクル対応が事実上必須になった。そして、これら3つはバラバラの機能追加ではなく、「コアを薄くし、周辺を差し替え可能にする」という一本の設計思想でつながっている、というのがこの記事の主題です。
Flutter は Google が開発するオープンソースのUIフレームワークです。Dart という言語で書いた単一のコードベースから、
を生成できます。「Write once, run anywhere」を謳うフレームワークは過去にいくつもありましたが、Flutterの特徴はOSのUI部品を借りてくるのではなく、自前の描画エンジンで画面を全部描くという割り切りにあります。だからこそ全プラットフォームでピクセル単位で同じ見た目を出せる一方で、「描画エンジン」と「デザイン部品」がフレームワークの心臓部に居座る構造になっていました。
Flutter 3.47 は、まさにその心臓部の構造そのものに手を入れるリリースです。個別の便利ウィジェットが増えた、という話ではありません。ここが今回いちばん押さえるべきポイントです。
| 用語 | 意味 |
|---|---|
| Material | Google発のデザインシステム。Androidらしい見た目のウィジェット群 |
| Cupertino | Appleのヒューマンインターフェースに寄せたデザインシステム。iOSらしい見た目のウィジェット群 |
| pub.dev | Dart/Flutter の公式パッケージレジストリ(npm や PyPI に相当) |
| Skia | Flutterが長年使ってきた2Dグラフィックスライブラリ。Chromeなどでも使われている |
| Impeller | Skiaを置き換えるために一から作られたFlutterの次世代レンダリングエンジン |
| Wasm(WebAssembly) | ブラウザ上でネイティブに近い速度で動くバイナリ形式。JavaScriptより高速な実行が期待できる |
これまで Material と Cupertino は、FlutterのコアSDKに直接同梱されていました。import 'package:flutter/material.dart'; と書けば使える、あの状態です。
公式の説明によれば、この「同梱」構造こそが開発速度のボトルネックでした。デザインライブラリの改善がコアSDKのリリースサイクルに縛られ、外部からのコントリビュートもしづらかったからです。
3.47 では、これらが独立パッケージとして pub.dev 上で 1.0 に到達しました。
公式が挙げているメリットは3点です。
これは業務システムを長期保守する立場だと非常に大きい。「デザインの新コンポーネントが欲しいだけなのに、SDKを丸ごと上げてビルドが全部壊れる」という事故を回避できます。
独立パッケージ側は週次リリースを予定しており、四半期ごとのSDKリリースを待つ必要がなくなります。バグ修正の到達が単純に速くなる。
独自デザインシステムを構築しやすくなる、という長期の布石です。
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 の中身は今使っているものと同一であり、移行してもウィジェットの挙動が変わるわけではない。凍結はこのリリースで解除され、今後は新パッケージ側で週次に修正・機能が流れてくることになります。
この秋にAppleの次期OSが来るのに合わせ、地ならしが入りました。iOS/macOSアプリを配信している人はここが一番、実害に直結するセクションです。
| プラットフォーム | 従来の最低 | 3.47以降の最低 |
|---|---|---|
| iOS | 13 | 15 |
| macOS | 10.15 | 12 |
Xcode 27 をサポートするための引き上げです。医療機関や自治体など、端末更新サイクルが長い現場に納品している場合は、顧客の端末OSバージョン分布を先に確認する必要があります。
UIScene ライフサイクル対応が必須化UIScene とは、iOS 13で導入された「1つのアプリが複数のウィンドウ(シーン)を持てる」ことを前提としたアプリのライフサイクル管理の仕組みです。従来の AppDelegate 中心のライフサイクルに代わるものとして用意されていました。
iOS 27 SDK では、この UIScene ライフサイクルが UIKitベースの全アプリで必須になります。公式の記述は明快で、Xcode 27 でビルドされた UIScene 非対応アプリは起動時に失敗するとされています。
AppDelegate に独自のネイティブコードを書いている場合、または 旧ライフサイクルに依存したプラグインを使っている場合は、手動移行が必要。該当しそうな心当たりがあるなら、Appleのベータ版が出ている今のうちに検証しておくべきです。公式も「初日に驚かないよう、今のうちにAppleのベータでテストを」と推奨しています。移行手順は UIScene/Delegate Adoption Guide にあります。
AppleのApple Silicon移行に合わせ、FlutterもIntel Macサポートを段階的に終了していきます。
ARM64のみのmacOSアプリを今すぐ作ることもできます。
flutter config --enable-macos-arm64-only
ビルドマシンにIntel Macを残している現場は、計画的な入れ替えを検討する時期です。
CocoaPods は長らくiOS/macOS開発で使われてきた依存関係管理ツール、Swift Package Manager(SwiftPM) はApple公式の後継にあたる仕組みです。Flutterはこの移行を進めています。
flutter config --enable-swift-package-manager で再挑戦できる。自作プラグインを公開している場合は、移行ガイドを確認しておきましょう。なお本リリースではコミュニティコントリビュータによってSwiftPMの不要なスキームをビルド初期に除外する改善が入り、ビルド時間も最適化されています。
Flutter Web の実行形式を WebAssembly(Wasm)をデフォルトにする方向で作業が進んでいます。狙いは明快で、ブラウザ上でネイティブに近いパフォーマンスを出すことです。
今日から試せます。
flutter build web --release --wasm
Wasm を使うには、JS interop(DartとJavaScriptの相互運用)を新しい package:web に移行しておく必要があります。 従来の dart:html ライブラリはサポートされません。
ただし公式は「プロジェクトの依存パッケージを最新に上げるだけで、この手のレガシーinterop問題は自動的に解消することが多い」とも書いています。まず flutter pub upgrade を回してから --wasm でビルドを試すのが早い、ということです。
遅延ロード(deferred loading) は、アプリ全体を最初に読み込まず、必要になった時点でモジュールを分割ロードする仕組みです。初期表示を速くするための古典的かつ強力な手法ですが、これが Wasm でも使えるようになりました(mainチャンネルでフラグ付きの実験的サポート)。
flutter build web --release --wasm --enable-wasm-deferred-loading
管理画面やダッシュボードのような画面数の多い業務系Webアプリでは、初期ロード時間が採用可否を左右することが多いので、これは実務的に重要な一手です。
Impeller は、Skia を置き換えるためにゼロから作られたFlutterの次世代レンダリングエンジンです。最大の特徴はシェーダのコンパイル戦略にあります。
シェーダとはGPU上で走る小さな描画プログラムのこと。従来のSkiaベースの構成では、これを実行時に動的にコンパイルしていました。その結果、あるアニメーションを初めて再生した瞬間だけカクつく現象 —— シェーダコンパイルジャンク(shader compilation jank) が発生していました。Flutterに触れたことがある人なら、「初回だけ妙に引っかかる」あの挙動に心当たりがあるはずです。
Impeller は Metal(macOS)や Vulkan(Windows / Linux)といったモダンなハードウェアAPIを直接ターゲットにし、シェーダを固定セットとしてビルド時にコンパイルします。結果として、最初の1フレーム目から一貫して滑らかなトランジションが得られます。
3.47 では、これが macOS / Windows / Linux でデフォルトになりました。
| プラットフォーム | 無効化方法 |
|---|---|
| macOS | Info.plist の FLTEnableImpeller を false に |
| Windows | main.cpp に project.set_impeller_switch(flutter::ImpellerSwitch::Disabled) |
| Linux | my_application.cc で fl_dart_project_set_enable_impeller(project, FALSE) |
ただしこのフォールバックは将来のリリースで削除されると明言されています。Skiaに戻さざるを得なかった場合は、回避策として使うのではなくバグ報告を上げてほしい、というのが公式のスタンスです。ここは「移行猶予」ではなく「移行完了までの最終区間」と読むべきでしょう。
あわせて macOSでは Wide Gamut Color(広色域)がデフォルトで有効になり、対応ハードウェア上でより豊かで正確な色表現が得られます。
Impellerだけでなく、デスクトップは今回まとまった強化が入っています。Flutterがデスクトップを本気で一級市民として扱い始めたと読める内容です。
マルチウィンドウ(実験的) — Canonical(Ubuntuの開発元)との協業で進行中。
windowHandle を取得可能に。 ネイティブウィンドウへの直接ポインタ(HWND / NSWindow / GtkWindow)が取れるため、Windowsのドッキング可能なペインのような高度なネイティブ機能に手が届きます。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 でより鮮明なテキストと綺麗なベクター曲線が得られます。
Widget Preview は、アプリ全体をビルド・起動することなく、個々のUIコンポーネントだけを即座に描画・確認・反復できる機能です。今回 stable になりました。
.widget_preview/ フォルダによるローカルプロジェクトキャッシュで起動が高速化。毎回のセットアップオーバーヘッドが消えます。PreviewThemeData API により、テーマを順に重ねた複雑なマトリクステストが可能に。ライト/ダーク × ブランドテーマ、といった検証が楽になります。web/ アセットを自動で同期。カスタムテーマや index.html のカスタマイズもそのまま反映されます。GenUI(Generative UI) は、AIエージェントがコンテンツを生成するだけでなく、それをどう表示しどう操作可能にするかまで決めるというUXパターンです。Flutterではこれを genui パッケージで実装します。
その下敷きになっているのが A2UI(Agent-to-UI) —— エージェントとクライアント(レンダラ)がUIの構成と状態を協調して決めるためのオープンプロトコルです。噛み砕くと、LLMが「UIそのもの」をJSONで吐き、Flutter側は開発者が許可したウィジェットカタログの範囲内でそれを実際のウィジェットとして描画する、という仕組みになります。コード生成ではなく、実ウィジェットの実行時合成である点がポイントです。
3.47のタイミングで genui の 0.10.0 がリリースされ、
a2ui_coreが入りました。後者は体感速度に効く実務的な改善です。
補足として、A2UIとgenuiは執筆時点でまだ活発に仕様が動いている領域です(プロトコルはv0.9系、genuiパッケージもアルファ扱いの記述が残っています)。今すぐ本番の中核に据えるより、プロトタイプで検証する段階と捉えるのが妥当でしょう。
flutter.compileSdkVersion = API 36 / flutter.targetSdkVersion = API 36 / flutter.minSdkVersion = API 24)を使うことが推奨されています。数値を直書きせず変数を使え、という指針は、将来のリリースでビルドを壊さないための保険です。(このあたりは地味ですが、証明書まわりのトラブルシュートに費やす時間を考えると効きます)
FlutterEngine::PostPlatformThreadTask で重い処理をプラットフォームスレッド外に逃がせるように。MediaQueryData.highContrast / MediaQueryData.invertColors)。Text.rich 内のネストしたテキストスパンがセマンティクスツリー上でレイアウト順と一致するように。BlockSemantics にキーボードフォーカスのブロックを追加。SelectableRegion のクラッシュ修正など。EdgeDraggingAutoScroller がアクティブなスクロールビューの ScrollPhysics を尊重するように(ロックされたリストでの自動スクロールを防止)。ImageIcon の useOriginalColors: true で元の色を保持、AnimatedCrossFade でクリッピング挙動を指定可能、ImageStreamListener で画像ストリームのエラーを直接追跡可能に。ここからは、3.47の内容とFlutterの2026年ロードマップを突き合わせた筆者の読みです。
これが最大の変化だと考えています。
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のデフォルトと戦う、という状況は不健全です。デザインシステムを外に出すことは、フレームワークが特定のデザイン言語にハードコードされている状態からの脱却であり、成熟したフレームワークが必ず通る道でもあります。
Impellerのデスクトップデフォルト化と、フォールバック(Skiaへの退避)を将来削除すると明言したこと。この2つはセットで読むべきです。
Flutterは長年、SkiaとImpellerという2つのレンダリングパスを並走させてきました。並走は互換性の保険になる一方、テストマトリクスは倍になり、パフォーマンス最適化は分散します。「バグを報告してほしい、回避策として使い続けないでほしい」という書き方は、保険期間の終了予告です。
これはFlutterが性能面での言い訳を潰しにきているということでもあります。「初回アニメーションがカクつく」はFlutter批判の定番でしたが、それを構造的に消しにかかっている。デスクトップでのSDFレンダリング採用(=デスクトップは画素密度が低い代わりにGPU演算に余裕がある、というプラットフォーム特性への最適化)も、「全プラットフォーム同一」から「プラットフォーム特性に合わせた最適化」へという成熟のサインです。
Flutter Web はこれまで、正直に言えば「動くには動く」というポジションでした。JavaScriptにコンパイルされる以上、実行速度には天井がある。
Wasmをデフォルトにするという意思決定は、この天井を外しにいくものです。ロードマップにも「ネイティブ品質の体験と性能を届けるため、WebではWasmをデフォルトにする意図がある」と明記されています。加えて今回のWasmでの遅延ロード実験は、「小さなデモは速いが実アプリは重い」という次の壁への対処です。
実務的な含意は明確です。「モバイルアプリを作ったついでにWebにも出す」から、「業務Webアプリの第一候補としてFlutterを検討する」への移行が視野に入ってきます。ただし前述の通り、dart:html 依存の古いコードを抱えている場合は移行が前提条件になります。まだWasmビルドを試していないなら、いま試すべきタイミングです。「デフォルトになってから慌てる」のが最悪のパターンなので。
GenUI / A2UI の位置づけは、他の3軸と比べると投機的です。しかし方向性としては一貫しています。
従来のアプリは、開発者がビルド時にウィジェットツリーを固定していました。GenUIはそれを覆し、エージェントに「使ってよいウィジェットのカタログ」と「目的」を渡すと、実行時に画面が組み上がるという発想です。アプリストアの審査を待たずに画面が変わる、と言えばインパクトが伝わるでしょうか。
ここでFlutterが持つ構造的な強みは、全プラットフォームで同一のウィジェット体系を持っていることです。「エージェントが吐いたUI記述を、iOSでもAndroidでもWebでもデスクトップでも同じように描画できるレンダラ」を提供できるフレームワークは、そう多くありません。軸1のデザインシステム分離(=ウィジェットカタログを差し替え可能にする)とも綺麗に噛み合います。
一方で、ここは冷静さも必要です。プロトコルはまだ0.9系で、SDKもアルファ。「UIをモデルに任せる」ことの品質保証をどうするかという問題は未解決です。業務システム、特に医療や金融のように画面の挙動が決定的であることが要件になる領域では、当面は「エージェントが生成した画面が想定外の状態を作らないこと」を保証する設計が別途必要になります。触っておく価値は高いが、任せきりにするのはまだ早い、というのが現時点の妥当な距離感でしょう。
Flutter 3.47 は、「多機能なフレームワーク」から「堅牢で薄い基盤 + 交換可能なエコシステム」への転換点です。派手な新ウィジェットはありませんが、構造を作り替えるリリースは、たいていの場合その後の数年を決めます。
そして忘れてはいけないのは、この転換が移行コストとして開発者に降りてくることです。11月の非推奨化までに、手を打つ時間はあまり長くありません。
3.47 を受けて、いま確認すべきことを優先度順に整理します。
優先度: 高(この秋までに)
AppDelegate に独自ネイティブコードがある、または古いプラグインを使っている → UIScene 移行の要否を判定し、Appleベータで検証するdart fix --apply --code=migrate_design_widgets を検証ブランチで一度回してみる(11月の非推奨化まで待たない)優先度: 中(半年以内に)
flutter build web --release --wasm を試し、dart:html 依存の有無を洗い出す優先度: 低(余力があれば)
*本記事は Flutter 3.47 の公式リリースブログ(2026年8月12日公開)の内容をもとに構成しています。「考察」セクションは公式の記述と2026年ロードマップを踏まえた筆者の解釈であり、公式見解ではありません。*