Flutter 3.47 release guide • Updated August 14, 2026
Flutter 3.47 New Features: The Complete Guide to Dart 3.13, Impeller, Wasm, Widget Previews and More
Flutter 3.47 is not a small maintenance release. It changes how Material and Cupertino are distributed, makes Impeller the default renderer on desktop, stabilizes Widget Previews, pushes Flutter Web closer to WebAssembly by default, prepares apps for Apple's next platform cycle, and arrives with Dart 3.13.
Flutter 3.47 landed on August 12, 2026, only two days before this guide was prepared. The headline change is easy to summarize but bigger than it first sounds: Material and Cupertino can now live outside the Flutter SDK as standalone packages. That decision gives Flutter's design libraries their own release cadence and starts separating the framework core from a particular visual design system.
That is only one part of the release. Flutter 3.47 also turns on Impeller by default for macOS, Windows and Linux, makes Widget Previews stable, expands experimental multi-window desktop APIs, introduces flavors on Windows and Linux, prepares for Xcode 27 and the next Apple OS releases, and keeps moving Flutter Web toward WebAssembly. Alongside it, Dart 3.13 makes primary constructors stable and adds a collection of useful language, tooling and runtime improvements.
Flutter 3.47 at a glance
The official release announcement describes Flutter 3.47 as a move toward a more modular framework. That theme appears repeatedly throughout the release: design libraries are decoupled, desktop rendering is modernized, platform integrations are getting more explicit, and web compilation is being prepared for a Wasm-first future.
material_ui and cupertino_ui reach 1.0 and are opt-in.1. Material and Cupertino are now standalone packages
This is the change most likely to define the direction of future Flutter releases. For years, Material and Cupertino widgets have been imported from the SDK itself:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
Flutter 3.47 introduces production-ready 1.0 versions of material_ui and cupertino_ui on pub.dev. The old SDK-bundled libraries still exist in 3.47, so an existing application does not break just because you upgraded the SDK. The new packages are an opt-in migration for this release.
Why Flutter is doing this
Bundling design systems directly inside the SDK meant that a Material or Cupertino improvement generally had to wait for a Flutter SDK release. By moving those libraries to pub.dev, Flutter can ship design fixes and components independently. The Flutter team says releases for these packages are currently planned on roughly a weekly schedule.
There is a second, longer-term benefit. Once the SDK core is less tightly coupled to Material or Cupertino, Flutter can move toward a more style-neutral foundation. That matters for teams that build their own design systems, use a brand system that does not closely follow Material, or maintain large cross-platform products where the design layer needs a release rhythm separate from the SDK.
How to migrate
Flutter provides an automated fix:
dart fix --apply --code=migrate_design_widgets
The migration updates applicable imports to the new packages. If the tool cannot update pubspec.yaml correctly, the Flutter release notes suggest adding the packages manually and running the fix again:
flutter pub add material_ui
flutter pub add cupertino_ui
dart fix --apply
Do package authors need to be more careful?
Yes. An application can usually control its own migration timing. A package that exposes Material or Cupertino types through its public API has a broader compatibility concern. The official Flutter post explicitly advises ecosystem package authors to treat this migration as a major release because consumers may still be using the legacy SDK imports.
Flutter also announced that formal deprecation of the original SDK-bundled design libraries is planned for the stable release expected in November 2026. That is not the same as saying they disappear in Flutter 3.47, but it is a clear signal that package maintainers should start planning.
2. Localizations move with the design systems
The split is not limited to visual widgets. Material and Cupertino localization data is also being moved into the standalone packages. In older apps, a typical setup imports flutter_localizations and manually includes global Material, Cupertino and Widgets delegates.
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter/material.dart';
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
With the new package structure, the design-specific localization resources live with the design packages. The Material package also exposes a combined delegates collection:
import 'package:material_ui/material_ui.dart';
localizationsDelegates: GlobalMaterialLocalizations.delegates,
That combined collection includes the required Cupertino and Widgets delegates as well, reducing the amount of setup code.
MaterialUiCompatibilityBridge helps mixed projects
Real projects rarely migrate every dependency at the same moment. Flutter 3.47 addresses that problem with MaterialUiCompatibilityBridge. Your app can move to the standalone Material package while a dependency still expects the older SDK-provided Material environment.
MaterialApp(
builder: (context, child) {
return MaterialUiCompatibilityBridge(
child: child!,
);
},
home: const HomeScreen(),
);
This bridge is particularly useful during the ecosystem transition. It is not a reason to ignore old dependencies forever, but it prevents a synchronized "everything must migrate today" problem.
3. Impeller becomes the default renderer on desktop
Flutter's modern rendering engine is no longer mainly a mobile story. In Flutter 3.47, Impeller is the default renderer on macOS, Windows and Linux.
Impeller was designed around predictable rendering work. Rather than relying on runtime shader compilation in ways that can cause a noticeable first-use stutter, it prepares a fixed shader set ahead of time. Flutter's goal is smoother and more consistent animation, particularly on the first run of an effect.
Can you still turn Impeller off?
For now, yes. Flutter 3.47 still documents temporary opt-out mechanisms:
- macOS: set
FLTEnableImpellertofalseinInfo.plist. - Windows: use
project.set_impeller_switch(flutter::ImpellerSwitch::Disabled)in the runner. - Linux: call
fl_dart_project_set_enable_impeller(project, FALSE).
Wide-gamut color is enabled on macOS
Flutter 3.47 also enables wide-gamut color by default on supported macOS hardware. This is most noticeable in visual products: photography, media, illustration, charting, design tools and apps with strong color branding. Teams that do color-sensitive work should test both wide-gamut and ordinary displays rather than assuming they render identically.
Sharper text through SDF rendering
Impeller on desktop now uses Signed Distance Function (SDF) rendering for sharper text and cleaner vector curves on macOS, Windows and Linux. Desktop screens often have lower pixel density than modern phones while having plenty of GPU headroom. SDF is a good fit for that environment and should be especially welcome in dense desktop interfaces such as IDE-like tools, dashboards and productivity software.
4. Desktop Flutter gets more capable
Flutter 3.47 contains several changes that make desktop applications feel less like stretched mobile apps and more like native desktop software.
Experimental popup windows
Windows and Linux gain popup-window support through Flutter's experimental multi-window work. Popup windows are useful for context menus, utility palettes, floating inspectors and other UI that naturally belongs outside the bounds of a single application window.
Native window handles
Platform-specific window controllers can expose the underlying native window handle, including HWND on Windows, NSWindow on macOS and GtkWindow on Linux. That is a low-level capability, but it opens the door to integrations Flutter does not expose through its cross-platform APIs, such as advanced window docking or native desktop extensions.
Sized-to-content windows
A new sized-to-content API allows regular windows and dialogs to size themselves to their Flutter content. That reduces the amount of manual dimension logic needed for compact tools, settings windows and desktop dialogs.
Focus and realization fixes
On Windows, Flutter fixed several cases where activating one window could bring unrelated background windows forward or interfere with focus after app resume. On Linux, newly created windows are explicitly realized before receiving their first compositor frame, fixing early rendering warnings and compositor assertions.
Flavors on Windows and Linux
Flutter flavors are now supported on Windows and Linux. That means one codebase can produce different desktop variants for development, staging, production, white-label customers or enterprise editions.
flutter build windows --flavor production
flutter build linux --flavor staging
Flavor-specific assets can be described in pubspec.yaml as well. For teams already using flavors on Android and iOS, this makes environment management much more consistent across all targets.
5. Flutter Widget Previews are now stable
Widget Previews graduate to stable in Flutter 3.47. The idea is simple: render and iterate on an individual widget without launching the entire application and navigating through several screens just to reach the component you are working on.
Faster startup with project caching
Preview infrastructure is cached in a local .widget_preview/ directory, avoiding repeated setup work. That matters because preview tools only become part of a developer's normal workflow when opening them feels immediate rather than ceremonial.
More flexible preview theming
The abstract PreviewThemeData API supports sequential theme layering. In practice, this makes it easier to test components across matrices such as light and dark mode, brand variations, typography changes and accessibility configurations.
Better web preview behavior
Widget Previews can synchronize assets from the host project's web/ directory and respect more of the project's actual web setup. That closes a common gap where a component looks correct in an isolated preview but differs once loaded inside the real web application.
GenUI 0.10.0 is highlighted alongside the release
Flutter's 3.47 announcement also calls out progress in the wider GenUI ecosystem. Version 0.10.0 adds an a2ui_core package that centralizes protocol-related classes and introduces support for A2UI client-side functions. Those functions let an agent direct small pieces of client-side work, such as validation or derived-value calculations, without requiring a round trip. This is an ecosystem package update rather than a core Flutter framework feature, but it is part of the release story for teams building agentic Flutter experiences.
6. Flutter Web keeps moving toward WebAssembly by default
Flutter has not flipped the Wasm-default switch in 3.47, but the direction is clear. The team is actively working toward making WebAssembly the normal compilation target for Flutter web applications.
You can test a production Wasm build now:
flutter build web --release --wasm
The important compatibility change: move away from dart:html
dart2wasm does not support the legacy dart:html library. Flutter recommends the modern JS interoperability stack, especially package:web and dart:js_interop. In many projects the fastest first step is simply updating dependencies, because popular packages have already migrated. If your own application directly imports dart:html, however, that code needs attention.
Experimental deferred loading
Flutter's announcement also highlights experimental Wasm deferred loading. The idea is to split a large web application into smaller lazy-loaded modules rather than forcing users to download every feature up front. That could become important for large Flutter web products where initial payload size is a major performance constraint.
flutter build web --release --wasm --enable-wasm-deferred-loading
7. Flutter 3.47 prepares for Xcode 27, iOS 27 and macOS 27
Apple platform work is one of the most consequential parts of the release because it changes minimum supported OS versions and application lifecycle expectations.
Minimum iOS version increases to iOS 15
Flutter 3.47 raises the minimum supported iOS version from iOS 13 to iOS 15. If your application still has meaningful users on iOS 13 or 14, this is not a cosmetic change. Check your analytics and product support policy before moving the production branch.
Minimum macOS version increases to macOS 12
The minimum supported macOS version rises from 10.15 to macOS 12. Desktop apps used in managed enterprise fleets should confirm deployment targets carefully because older Macs tend to remain in service longer than consumer mobile devices.
UIScene lifecycle becomes important
The iOS 27 SDK requires the UIScene lifecycle for UIKit applications. Flutter's CLI can migrate standard projects automatically during the build, but custom native application code is the area to inspect closely. A customized AppDelegate or a plugin that relies on the older lifecycle can require manual migration.
Intel Mac support is winding down
Flutter has stopped automated test runs on Intel Mac hardware and now warns when developers build on Intel hosts or target dual Mac architectures. The team says these warnings are expected to become errors in a future release.
flutter config --enable-macos-arm64-only
If your customer base is already Apple Silicon-only, the command above lets you opt into ARM64-only macOS builds now.
Swift Package Manager adoption keeps growing
At the time of the 3.47 announcement, Flutter reported that 92 of the top 100 iOS plugins had migrated to Swift Package Manager. If you previously disabled SwiftPM because of plugin compatibility problems, this is a good release to re-test it:
flutter config --enable-swift-package-manager
Flutter also improved build performance by filtering unnecessary SwiftPM package schemes earlier in the build pipeline, and the CLI now presents clearer signing information, including Team ID and Team Name when selecting certificates. Provisioning profile errors have also been improved.
8. Android changes and the Flutter 3.47 dependency matrix
The Android side of this release is less dramatic than the design-system split, but it contains changes that matter for build stability and CI environments.
| Android tool | Flutter 3.47 verified version |
|---|---|
| Java | 17 minimum |
| Kotlin Gradle Plugin | 2.4.0 |
| Android Gradle Plugin | 9.1.0 |
| Gradle | 9.3.1 minimum for AGP 9.1.0 |
The default API-level variables exposed by the Flutter SDK for this release are:
flutter.compileSdkVersion: API 36flutter.targetSdkVersion: API 36flutter.minSdkVersion: API 24
Where possible, use Flutter's standard Gradle variables rather than duplicating those numbers as hard-coded values in several files. That reduces friction when future SDK releases change their tested defaults.
Virtual keyboard modifier fix
Flutter also fixes an Android issue where virtual keyboard modifier keys such as Shift could become stuck. The key responder now avoids synthesizing inappropriate physical-key events for virtual keyboard input.
AGP 9 and built-in Kotlin
The Android ecosystem is moving toward AGP 9's built-in Kotlin model. Projects with older, heavily customized Gradle configuration should review their plugin setup instead of assuming old Kotlin Gradle Plugin behavior will continue unchanged forever.
9. Framework, accessibility, text and platform polish
A large Flutter release always includes hundreds of smaller pull requests. Most are not headline material on their own, but several directly affect the quality of real applications.
Android accessibility settings are detected automatically
Flutter now reflects Android high-contrast and color-inversion settings through MediaQueryData.highContrast and MediaQueryData.invertColors. Apps can respond more naturally to a user's device-level accessibility preferences.
Rich text semantics are more predictable
Nested spans inside Text.rich are ordered more accurately in the semantics tree relative to their visual layout. Flutter also adds keyboard focus blocking behavior for BlockSemantics.
Text selection feels more stable
Selection handles on mobile now behave better during small scroll movements, keyboard shortcuts can dismiss open selection menus, and Android selection handles are less likely to obscure the context menu near the top of the screen. Flutter also fixes a SelectableRegion crash that could occur when selection started inside an empty scrollable area, plus highlighting artifacts on faded selectable text.
Better embedded iOS view gestures
Gesture propagation is improved for native iOS platform views embedded inside Flutter. This is relevant to plugins that wrap UIKit controls and to applications that mix Flutter UI with native views.
EdgeDraggingAutoScroller respects ScrollPhysics
EdgeDraggingAutoScroller now respects the active scroll view's ScrollPhysics. A list that is intentionally non-scrollable should no longer begin scrolling simply because a draggable object reaches its edge.
Small APIs that are useful in everyday UI work
ImageIconcan preserve the original asset colors withuseOriginalColors: true.AnimatedCrossFadegains aclipBehaviorparameter.ImageStreamListenerimproves direct image-stream error tracking.- Flutter's detailed changelog also exposes application build name and build number more conveniently as compile-time constants.
Windows and Linux refinements
Windows fixes caret positioning for Korean IME composition. Windows plugin authors can schedule expensive work away from the platform thread through FlutterEngine::PostPlatformThreadTask. Linux adds stylus rotation and pressure reporting, which is useful for drawing, handwriting and graphics applications.
10. Two Flutter 3.47 breaking changes to check carefully
OpenGL ES render-to-texture orientation
Impeller's OpenGL ES backend now stores render-to-texture content top-down, matching Flutter's Metal and Vulkan paths. This mostly affects developers writing custom fragment shaders or low-level graphics code that directly samples render-target textures.
Older code may contain an OpenGL ES-specific vertical flip similar to this:
#ifdef IMPELLER_TARGET_OPENGLES
uv.y = 1.0 - uv.y;
#endif
On the new behavior, that workaround can turn into the bug and make your texture appear upside down. Normal framework rendering is expected to handle the orientation internally; the risk is primarily in custom shader code written around the old backend behavior.
Accessibility headings should use headingLevel
On Android and iOS, the older Semantics(header: true) approach no longer declares a section heading in the way developers may expect. Use headingLevel instead:
Semantics(
headingLevel: 1,
child: const Text('Account Settings'),
)
This produces clearer cross-platform semantics and maps more naturally to heading levels on the web.
11. Dart 3.13 ships alongside Flutter 3.47
Flutter 3.47 arrives with Dart 3.13, released on the same day. The language headline is the stabilization of primary constructors, but the release also improves formatting, JavaScript interop, pub workspaces, isolates, native library tree shaking and several core APIs.
Primary constructors are stable
A traditional model might look like this:
class Product {
final String name;
final double price;
Product(this.name, this.price);
}
Dart 3.13 can express the same idea much more concisely:
class Product(
final String name,
final double price,
);
Primary constructors are more than a shorthand for tiny model classes. Dart supports declaring and non-declaring parameters, named and private primary constructors, super parameters, enum primary constructors and constant primary constructors.
Concise constructor syntax
Dart 3.13 also supports a concise constructor form using keywords such as new and factory inside the class body without repeating the class name. This reduces repetition and can make class renaming less noisy.
New lints and refactorings
Dart adds lints that help teams adopt the new constructor style consistently, including empty_container_bodies, initialize_in_field_declaration, unnecessary_primary_constructor_body, unnecessary_type_name_in_constructor and use_declaring_parameters. There is also an experimental use_primary_constructors lint.
IDE tooling can convert a traditional constructor to a primary constructor, convert back, turn parameters into declaring parameters and move initialization into field declarations. That matters when introducing the syntax to an existing codebase; adoption does not have to be a manual rewrite.
New core APIs
Future.pause(...)adds another way to pause asynchronous execution.List.unmodifiableOf(...)andMap.unmodifiableOf(...)offer improved static typing for unmodifiable collections.int.oneBitCountandint.trailingZeroBitCountprovide efficient bit operations.InterfaceAddressindart:ioadds network-interface information such as prefix length and broadcast data.- File timestamps preserve microsecond precision.
Advanced isolate APIs
Dart 3.13 adds advanced isolate capabilities such as Isolate.runSync, Isolate.create, Isolate.shutdownSync, Isolate.pinToCurrentThread and Isolate.runEventLoopSync. Most application code will not need these APIs, but they are significant for embedders, runtime integrations and specialized concurrency systems.
JavaScript interop gets stronger typing
JSFunction and JSExportedDartFunction become generic, improving compile-time type safety when calling between Dart and JavaScript. Dart also adds JSObject.getPrototypeOf. These changes line up with Flutter Web's broader move away from legacy browser libraries.
Formatter changes
dart format continues to refine call-chain formatting, import grouping, primary constructor layout, enum formatting, parameter-list blocks, as/is expressions and several edge cases that previously produced awkward line breaks. Some formatting changes are language-versioned, so they appear once a package moves to Dart 3.13.
IDE and analyzer improvements
The analysis server now supports LSP Inline Values, allowing compatible editors and debuggers to display variable evaluations inline during active debugging. Dart also adds language-server methods for Flutter Widget Preview metadata, which helps IDE integrations discover and present available previews.
For stricter codebases, new no_raw_types and no_dynamic_casts lints replace the older strict analysis options with lint-based equivalents. A new async_return_with_no_await lint flags suspicious async functions that return non-Future values without actually awaiting anything.
Pub workspace commands
Monorepo users get a useful command:
dart pub workspace list
It lists the packages in a pub workspace and their paths, with JSON output available for scripts and CI. Dart 3.13 also introduces dart pub cache preload for loading package archives directly into PUB_CACHE.
Dart CLI cross-compilation
dart build cli now supports cross-compilation through --target-os and --target-arch. That is mainly a Dart command-line/server feature, but it is useful for Flutter teams that also ship companion tools, generators or deployment utilities from the same monorepo.
Native library tree shaking with @RecordUse
One of the most technically interesting improvements is native-library tree shaking. Dart code that wraps FFI libraries can already be tree-shaken, but the native library may still contain symbols the application never calls. Dart 3.13 introduces @RecordUse and tooling support that allows the native link stage to understand which bindings are reachable.
For packages that integrate the feature, unused native object files and exports can be removed. If an app never invokes a package's native bindings at all, its native binary can potentially be left out of the final bundle. Large SQLite, codec, cryptography, media or Rust/C++ integrations are the kinds of dependencies that can benefit most.
Runtime, WebAssembly and dynamic-module work continues
Dart 3.13 also includes runtime hardening work such as a memory cage around the Dart heap, ongoing compiler/analyzer infrastructure convergence, and experimental deferred loading for dart2wasm. The Dart team is also exploring dynamic module linking as a longer-term capability. These are mostly under-the-hood or experimental improvements today, but they shape the performance and deployment story Flutter developers will see in future releases.
12. How to upgrade to Flutter 3.47 safely
For a personal project, upgrading can be as simple as running flutter upgrade. For a production app, a short migration checklist saves time later.
Step 1: create a clean rollback point
Commit your current working tree or create a dedicated upgrade branch. Do not combine unrelated feature work with the framework migration if you can avoid it.
Step 2: update Flutter stable
flutter channel stable
flutter upgrade
flutter doctor -v
Step 3: review dependencies
flutter pub outdated
flutter pub upgrade
Pay extra attention to packages that integrate native Apple code, custom desktop rendering, Web APIs, maps, video, camera, database engines or custom platform views.
Step 4: analyze and test
flutter analyze
flutter test
Run integration tests as well if your project has them. Static analysis cannot catch a rendering regression, native lifecycle problem or platform-specific focus issue.
Step 5: test every platform you actually ship
If your app supports Android, iOS, web and desktop, test all four categories. Flutter 3.47 contains enough platform-specific work that success on one target says little about another.
Step 6: test Flutter Web with Wasm
flutter build web --release --wasm
Search your source and dependencies for legacy dart:html usage if the build fails.
Step 7: audit Apple deployment targets
Confirm that dropping iOS 13/14 and macOS versions before 12 is acceptable for your audience. Test custom AppDelegate logic, deep links, notifications, Firebase initialization and plugins that hook into the app lifecycle.
Step 8: audit rendering-sensitive code
Desktop apps should test Impeller thoroughly. Check custom shaders, CustomPainter, image filters, blend modes, SVGs, video, maps, platform views and advanced clipping. If you have OpenGL ES-specific shader flips, inspect them for the 3.47 orientation change.
Step 9: audit semantics headings
Search for header: true inside Semantics and migrate genuine section headings to headingLevel.
Step 10: decide when to migrate Material/Cupertino
You do not have to migrate design packages in the same commit as the Flutter 3.47 upgrade. For mature apps, keeping those as separate changes may be the safer choice.
13. Should you upgrade to Flutter 3.47?
For new projects: Flutter 3.47 is a strong baseline. You get the current stable tooling, Dart 3.13, stable Widget Previews, desktop Impeller and a better position for the upcoming Apple and WebAssembly changes.
For actively maintained production apps: upgrading is sensible, but treat it as an engineering change rather than a version-number chore. The main questions are whether your Apple deployment minimums are acceptable and whether your application has rendering or native integration code that needs extra QA.
For libraries/packages: the standalone design-package migration deserves deliberate versioning. If your public API exposes Material or Cupertino types, make sure your consumers understand what changes.
For Flutter Web apps: even if you stay on the regular web compiler for production, add a Wasm build to CI or your release checks. Finding compatibility problems now is cheaper than discovering them when Wasm becomes the normal path.
Flutter 3.47 FAQ
What is new in Flutter 3.47?
The biggest Flutter 3.47 features are standalone material_ui and cupertino_ui packages, Impeller enabled by default on desktop, stable Widget Previews, more desktop windowing capabilities, Windows/Linux flavors, continued WebAssembly work, Apple platform preparation and the Dart 3.13 release.
When was Flutter 3.47 released?
Flutter 3.47 was released on August 12, 2026.
Which Dart version comes with Flutter 3.47?
Flutter 3.47 is paired with Dart 3.13. Dart 3.13 makes primary constructors stable and adds formatter, pub workspace, JS interop, runtime and native tree-shaking improvements.
Do I have to migrate from package:flutter/material.dart immediately?
No. The SDK-bundled Material and Cupertino libraries remain available in Flutter 3.47. The new standalone packages are opt-in for this release. Flutter has announced formal deprecation of the old bundled design libraries for a later stable release, so planning the migration now is still sensible.
Is Impeller now default on Flutter desktop?
Yes. Flutter 3.47 makes Impeller the default renderer on macOS, Windows and Linux. Temporary opt-out mechanisms still exist but are expected to be removed in a future release.
What is the minimum iOS version for Flutter 3.47?
The minimum supported iOS version is now iOS 15. The minimum supported macOS version is macOS 12.
Does Flutter 3.47 use WebAssembly by default?
Not yet. Flutter is working toward Wasm as the default for Flutter Web, and developers can test release builds with flutter build web --release --wasm.
How do I migrate to the standalone Material and Cupertino packages?
Start with dart fix --apply --code=migrate_design_widgets. If the migration cannot update pubspec.yaml, add material_ui and/or cupertino_ui manually, then run dart fix --apply again.
Official references used for this guide
Editorial note: This article focuses on developer-facing behavior and migration impact. The full Flutter 3.47 changelog contains many additional bug fixes, tests, refactors and documentation changes.








