跪拜 Guibai
← Back to the summary

Flutter 3.47 Decouples Material and Cupertino, Makes Impeller Default on Desktop

With the convening of Google I/O China, Flutter 3.47 has arrived as scheduled. The main updates this time include: Material / Cupertino officially decoupled from the Flutter SDK, Impeller becoming the default renderer for all PC platforms, Widget Preview moving to Stable, continued progress on Wasm defaulting, and migration adaptations for Xcode 27 / iOS 27 / macOS 27. It's a moderate update, but at least the PC side has been strengthened.

Decoupled Packages

First, the independent versions of material_ui and cupertino_ui 1.0 have finally been released. Previously:

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

Now you can switch to:

import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';

Of course, the most important thing is that Material / Cupertino are now updated independently from Flutter's quarterly Stable cadence. Flutter currently plans for these UI packages to release fixes and new features on a weekly cadence.

Of course, version 3.47 does not force you to migrate immediately; the old import methods still work. You can migrate using Flutter's automatic migration:

dart fix --apply --code=migrate_design_widgets

Migration within your App is generally fine; the main issue is with third-party packages, for example:

Your App
 ├── material_ui
 │
 └── plugin A
      └── package:flutter/material.dart

In such cases, old and new Material types might cause compatibility issues during the migration period. Flutter provides MaterialUiCompatibilityBridge to bridge this ecosystem migration gap, for example:

MaterialApp(
  builder: (context, child) {
    return MaterialUiCompatibilityBridge(
      child: child!,
    );
  },
)

The main role of MaterialUiCompatibilityBridge is: to bridge ThemeData and MaterialLocalizations, allowing legacy widgets that still depend on package:flutter/material.dart to work normally within the new widget tree, adapting the correspondence between flutter.material.Theme and material_ui.Theme in scenarios like Theme.of(context).

Of course, package developers also need to pay attention. For example, if you maintain a pub.dev package and migrate it from the old Material/Cupertino API to the standalone design package, you should release it as a major release, a major version break, because this is similar for users.

Also note that Localizations have also been split. Previously:

import 'package:flutter_localizations/flutter_localizations.dart';

localizationsDelegates: [
  GlobalCupertinoLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
]

Now the corresponding localizations for Material / Cupertino have also been moved to their respective packages. The official timeline states that the built-in package imports are planned to be officially deprecated in November this year, so it's best to check if your dependent packages are still maintained and whether migration is needed.

Impeller

Starting with Flutter 3.47, all three PC platforms have fully switched to Impeller by default. This means Flutter GPU and the various 3D rendering and gaming capabilities we mentioned before are officially supported on all platforms except Web. However, fallback interfaces are still provided:

The Desktop text issues we mentioned before have also been addressed. Flutter 3.47's Impeller Desktop now uses SDF (Signed Distance Function) for text and vector curve rendering. Because desktops generally have better GPU performance but often lower DPI, issues like blurry fonts are more common. SDF can leverage more GPU computation to achieve sharper, more stable edge performance.

Renderer optimizations are also being reworked for Desktop visual characteristics. Additionally, macOS has enabled Wide Gamut Color by default this time, supporting hardware rendering with a wider color gamut.

This wave finally brings a major boost to the PC side.

Flutter Multi-Window

Multi-window continues to make progress. For example, Windows / Linux now support popup windows, enabling some things that were previously difficult to make truly "desktop native," such as:

These scenarios now support being implemented through truly independent native windows, and you can even directly access the underlying native window. Now the platform-specific controller can obtain:

This capability is very practical. As we discussed in previous articles, this means when Flutter Desktop encounters capabilities not covered by the framework API, you can directly access:

Flutter
   ↓
windowHandle
   ↓
Win32 / AppKit / GTK

For example, the official Windows Dockable Pane demo shows that for truly complex Desktop Apps, this is a crucial escape hatch.

Additionally, several old multi-window issues have been fixed. For example, as we mentioned before, on Windows, activating one window might previously pull other background windows to the front, or windows might steal focus after the app resumes. These issues have been fixed.

Linux has also modified the window realization order to avoid warnings/assertions during the first frame. Additionally, sized-to-content has been added, allowing ordinary Windows/Dialogs to automatically calculate window size based on Flutter content.

The only pity is that it's still experimental.

Finally, Windows / Linux finally support Flavors. Now you can:

flutter build windows --flavor flavor_a

and

flutter build linux --flavor flavor_a

Assets can also be differentiated by flavor:

flutter:
  assets:
    - path: assets/flavor_a/images
      flavors:
        - flavor_a
    - path: assets/flavor_b/images
      flavors:
        - flavor_c

Xcode 27 / iOS 27 / macOS 27

Starting with Flutter 3.47, the new minimum supported version has been raised to 15 for iOS, and macOS has been raised to 12:

Platform Before Flutter 3.47+
iOS 13 15
macOS 10.15 12

At the same time, UIScene has become a mandatory requirement. Apps not adapted to UIScene will fail to launch directly on Xcode 27.

Additionally, Intel Mac support has been discontinued. Flutter 3.47 has stopped automated testing for Intel Macs, and Intel Macs are entering the phase-out stage. It is recommended to package directly using flutter config --enable-macos-arm64-only.

Finally, the SwiftPM migration is nearly complete. Among the Top 100 iOS Flutter Plugins, 92 have already migrated to Swift Package Manager:

Since Flutter 3.44, SwiftPM has become the default solution for iOS/macOS native dependency management. CocoaPods will continue to be supported but is in maintenance mode.

Of course, more importantly, the CocoaPods Registry will become permanently read-only on December 2, 2026.

Version 3.47 also optimizes the SwiftPM build pipeline by filtering out package schemes that don't need to be built in advance, so Flutter iOS/macOS projects using SwiftPM will see further build time optimizations.

Web

Wasm now supports Deferred Loading. Version 3.47 provides this experimentally on the main channel:

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

The goal is to split a very large Wasm file into multiple modules, loading only the core at startup and loading other code on demand. This can help solve the problem of pages opening too slowly.

Additionally, the official team has stated that flutter build web --release --wasm will become the default in the future. Flutter Web should completely shift to Wasm as its sole renderer going forward.

Android

The main update for Android this time is the baseline update, primarily:

Item Flutter 3.47
Java 17, minimum required
Kotlin Gradle Plugin 2.4.0
Android Gradle Plugin 9.1.0
Gradle 9.3.1

Additionally, the default Android API parameters provided by the Flutter SDK are:

compileSdkVersion = API 36
targetSdkVersion  = API 36
minSdkVersion     = API 24

That is, the default variable value currently provided by the 3.47 SDK suggests a minimum of 24.

Other

Other updates include:

Finally

This update is a relatively minor version update. The core is the formal logic of package decoupling, followed by a major boost to the PC side. Of course, although multi-window has made a big breakthrough, it still hasn't entered stable. But it's not a big problem; I've been using it for a while, and basic daily multi-window usage is generally fine.

So, young man, start trying the new crab.

Comments

Top 1 from juejin.cn, machine-translated. The original thread is authoritative.

懒洋君

Can assets also be differentiated by flavor, and does it support Android and iOS?