When Flutter 3.47 shipped on August 12, 2026, the headline story wasn't the rendering engine — it was the SDK's own skeleton: the Material and Cupertino design libraries are no longer tied exclusively to flutter/flutter. They still ship inside the SDK, but they're now also published on pub.dev as independent 1.0 packages named material_ui and cupertino_ui. This post walks through the Flutter 3.47 material_ui migration step by step: the automatic migration command, a known pubspec bug, what MaterialUiCompatibilityBridge is for, and the November deprecation timeline — sourced from official documentation.
💡 Pro Tip: Before you start migrating, confirm your SDK is actually 3.47 or newer withflutter --version— thedart fix --apply --code=migrate_design_widgetscommand isn't recognized on older versions.
Table of Contents
- What changed in 3.47, in one sentence
- Why Material/Cupertino separated from the SDK
- Release timeline
- Points that often confuse people
- Automatic migration with dart fix --apply --code=migrate_design_widgets
- The pubspec bug and the manual flutter pub add fix
- MaterialUiCompatibilityBridge
- The flutter_localizations split (GlobalMaterialLocalizations.delegates)
- The November deprecation timeline and the real risk
- Old vs new import paths comparison
- If you maintain a package: publish it as a major release
- Checklist
- Step-by-step migration strategy for large projects
- Impeller and other 3.47 headlines beyond the migration
- Verifying the migration with golden tests and CI
- FAQ
- What is the material_ui package in Flutter 3.47?
- How do you migrate to material_ui 1.0?
- Are Cupertino widgets being removed from the SDK?
- What does MaterialUiCompatibilityBridge do?
- Do I need to remove the flutter_localizations package from pubspec?
- What happens if I don't migrate?
- Conclusion
- Sources
What changed in 3.47, in one sentence
Flutter 3.47 split the Material and Cupertino design libraries out of the core SDK and turned them into independent 1.0 packages on pub.dev named material_ui and cupertino_ui. The Flutter team describes this in its official blog post as "a major milestone: decoupling the design systems from the core SDK." The same release also made Impeller the default rendering engine on macOS, Windows, and Linux, and moved Flutter Widget Previews to stable — but this post's focus is the package split and the practical migration steps.
In practice, this means the import 'package:flutter/material.dart'; lines in your project will lose validity soon, and should be replaced with import 'package:material_ui/material_ui.dart';. The libraries inside the SDK still work fine for now; nothing breaks suddenly. But the split is a turning point — like "tickets are now sold from a separate gate" — and the sooner you finish this migration, the calmer you'll be when the official November deprecation notice lands.
Why Material/Cupertino separated from the SDK
The Flutter team's reasoning is clear: embedded in the core SDK, the Material and Cupertino libraries were locked into its quarterly stable release cycle. The team froze contributions to these libraries in April 2026 to prepare for the split, and releases are now planned weekly. As an independent package, a small fix to a button component can reach pub.dev within days, instead of waiting for the next Flutter stable release.
This also opens the door to ecosystem contributions: these packages, now moved to the flutter/packages repository, can be developed with a lighter process than the core SDK. Practically, bug fixes and small improvements to Material components will now reach you much more often, independent of the SDK version number.
Release timeline
This split didn't happen overnight; the team prepared by freezing direct contributions in April 2026. After four months of preparation, both packages reached version 1.0 alongside 3.47. As of August 15, 2026 (this article's publish date), both are at 1.0.0; given the weekly cadence, minor versions are expected soon.
Points that often confuse people
A few points tend to confuse people the first time they hear about this transition. First: moving to material_ui and cupertino_ui is different from upgrading the Flutter SDK — if you've already upgraded to 3.47, you can keep working with the old imports; the package migration is a separate, optional step. Second: material_ui isn't just a subset of Material components — it's a complete Material 3 catalog, including app scaffolding, navigation, input components, theming, and internationalization. There's no in-between state where "some widgets stay on the old package": within a single file you use either the old import or the new one, but across the project you can roll out the migration module by module (see MaterialUiCompatibilityBridge). Third: cupertino_ui is the standalone version of Flutter's official iOS/macOS design library and works the same way — CupertinoApp, CupertinoButton, and every other component live here.
Another point of confusion is version numbers. These packages advance with their own version numbers on pub.dev, independent of the Flutter SDK; you'll see a dependency like material_ui: ^1.0.0 in pubspec.yaml, and it shouldn't be confused with your SDK version. Thanks to the weekly cadence, this number will advance much faster than the SDK's, which changes every three months — turning dependency updates into a more routine maintenance task than before.
Automatic migration with dart fix --apply --code=migrate_design_widgets
At the center of the migration is a single command. Run this from your project's root directory:
1dart fix --apply --code=migrate_design_widgetsThis replaces the package:flutter/material.dart and package:flutter/cupertino.dart imports with package:material_ui/material_ui.dart and package:cupertino_ui/cupertino_ui.dart respectively, and attempts to add the required dependencies to pubspec.yaml. On small and medium projects, this single command eliminates manual import changes. Before running it, make sure git status is clean — dart fix --apply applies the diff directly to your files, and you'll need version control to roll it back.
The pubspec bug and the manual flutter pub add fix
The Flutter team acknowledges in its official blog post a known early bug in this tool: dart fix --apply replaces the imports but may fail to add the new dependencies to the pubspec, so the project won't compile.
The fix is a two-step, officially recommended manual intervention:
1flutter pub add material_ui2flutter pub add cupertino_ui # only if you use Cupertino3dart fix --applyFirst you manually add the missing packages to pubspec.yaml, then re-run dart fix --apply (without the --code flag) to finish any remaining import fixes. This order resolves nearly every "imports changed but the package isn't in pubspec" type of build error.
MaterialUiCompatibilityBridge
In real projects, migration is rarely a single, instant flip: your app may have moved to material_ui, but if a third-party dependency still uses the old package:flutter/material.dart import, two different ThemeData/MaterialLocalizations trees can collide. For this, the Flutter team offers MaterialUiCompatibilityBridge: a bridging layer that lets your app move to the standalone packages right away, even while some dependencies still use the old core SDK imports.
You use it by wrapping it inside MaterialApp.builder or applying it only to the relevant subtree:
1MaterialApp(2 builder: (context, child) {3 return MaterialUiCompatibilityBridge(4 child: child!,5 );6 },7 home: const HomeScreen(),8)This isn't meant to be permanent — it's a temporary compatibility layer. Once you've confirmed all your dependencies have moved to material_ui/cupertino_ui, remove the bridge so you don't leave an unnecessary abstraction layer in the project.
The flutter_localizations split (GlobalMaterialLocalizations.delegates)
An important nuance: the flutter_localizations package hasn't disappeared and isn't deprecated. What's changed is that the localization delegates and translated strings for Material and Cupertino widgets now also live directly inside material_ui and cupertino_ui, alongside flutter_localizations. So the flutter_localizations dependency is no longer mandatory in a fully migrated project — removable from pubspec, though not required.
The new setup collapses what used to require listing three separate delegates in localizationsDelegates down to a single reference:
1MaterialApp(2 localizationsDelegates: GlobalMaterialLocalizations.delegates,3 supportedLocales: const [4 Locale('tr'),5 Locale('en'),6 ],7 home: const HomeScreen(),8)GlobalMaterialLocalizations.delegates now supplies all the delegates you need (Material, Widgets, and Cupertino) in a single line; GlobalCupertinoLocalizations offers the same pattern on the Cupertino side. This is confirmed with the exact same code sample in both Flutter's official blog post and the material_ui pub.dev README.
The November deprecation timeline and the real risk
The original Material and Cupertino libraries inside the SDK are planned to formally enter deprecation in the upcoming "Fall stable" release this November. As of August 15, 2026, the old package:flutter/material.dart imports are still fully functional, produce no warnings, and won't break your project. The real risk isn't urgency — it's neglect. Projects that haven't migrated by November will face compiler warnings once deprecation is announced, and eventually (the exact removal date isn't finalized yet) the in-SDK libraries being removed entirely.
That's why "no need to rush, but don't put it off either" fits perfectly here: the migration can be done mechanically with an automatic command, so there's no upside to leaving it until November.
Old vs new import paths comparison
Old (in-SDK) | New (standalone) | Status (Aug 15, 2026) |
|---|---|---|
package:flutter/material.dart | package:material_ui/material_ui.dart | Both work |
package:flutter/cupertino.dart | package:cupertino_ui/cupertino_ui.dart | Both work |
flutter_localizations (Material/Cupertino delegates) | Delegates inside material_ui / cupertino_ui | flutter_localizations became optional |
Three separate localizationsDelegates entries | GlobalMaterialLocalizations.delegates | Collapsed into one line |
If you maintain a package: publish it as a major release
If you maintain your own pub.dev package, this transition carries a different responsibility. The Flutter team's official recommendation is clear: migrating a package to these standalone packages should be treated as a major version bump in semver terms. The reason: if your package's public API exposes types like MaterialApp or ThemeData, those types are now defined in a different package — a potentially breaking change for anything depending on yours.
Tagging your release as major also gives users time to evaluate whether they need MaterialUiCompatibilityBridge. Stating in your changelog which imports changed and the minimum required material_ui/cupertino_ui version keeps downstream projects from hitting surprise build errors.
Checklist
Step | What to do |
|---|---|
1 | Run dart fix --apply --code=migrate_design_widgets |
2 | If you hit the pubspec bug, run flutter pub add material_ui (plus cupertino_ui if needed), then re-run dart fix --apply |
3 | Simplify the localizationsDelegates entry to GlobalMaterialLocalizations.delegates |
4 | Wrap screens that still depend on old-SDK imports with MaterialUiCompatibilityBridge |
5 | If you maintain a package, publish this transition as a major release |
6 | Complete the migration before the November deprecation, scan for old imports with flutter analyze |
Step-by-step migration strategy for large projects
On a small demo app, dart fix --apply --code=migrate_design_widgets gets you done in five minutes. But in a monorepo with hundreds of files and multiple feature teams working in parallel, one giant diff makes code review meaningless and raises merge-conflict risk. There, it's safer to split the migration along module boundaries: run dart fix on one feature module (say, lib/features/onboarding/), run the tests, merge that PR, then move to the next module.
It's useful to compare a widget file's imports before and after the migration:
1// Before migration2import 'package:flutter/material.dart';3import 'package:flutter/cupertino.dart';4 5class OnboardingScreen extends StatelessWidget {6 const OnboardingScreen({super.key});7 8 @override9 Widget build(BuildContext context) {10 return Scaffold(11 appBar: AppBar(title: const Text('Hoş geldin')),12 body: const Center(child: Text('Başlayalım')),13 );14 }15}1// After migration2import 'package:material_ui/material_ui.dart';3import 'package:cupertino_ui/cupertino_ui.dart';4 5class OnboardingScreen extends StatelessWidget {6 const OnboardingScreen({super.key});7 8 @override9 Widget build(BuildContext context) {10 return Scaffold(11 appBar: AppBar(title: const Text('Hoş geldin')),12 body: const Center(child: Text('Başlayalım')),13 );14 }15}Not a single character of the widget body changed — only the imports did. This is why the migration is low-risk: Scaffold, AppBar, and Text behave exactly the same inside material_ui; only the package's address changes.
A simple grep also helps quickly list which files still use the old imports:
1grep -rl "package:flutter/material.dart" lib/ | wc -l2grep -rl "package:flutter/cupertino.dart" lib/ | wc -lOnce the output of both commands drops to zero, that module's migration is complete — adding this as a CI step also prevents an old import from sneaking back in on a later PR.
Impeller and other 3.47 headlines beyond the migration
This split isn't the only headline. Impeller also became the default rendering engine on macOS, Windows, and Linux in the same release — previously default only on iOS and Android. For desktop-targeting projects, the rendering pipeline is changing; we cover any differences in renderer behavior in our Impeller rendering engine guide. Flutter Widget Previews also moved to stable in this release — independent of the material_ui/cupertino_ui split, but announced together in the same notes.
Reviewing your architecture during the migration? A layered structure makes it easier to isolate SDK changes like this one — see our Flutter Clean Architecture guide. On performance, it's also worth watching how shifting package boundaries in the widget tree can affect profiling output; see our Flutter performance optimization post.
Verifying the migration with golden tests and CI
After migrating, confirming your widget tests still pass is the most reliable way to prove the imports changed but behavior didn't. Our Flutter testing guide covers unit, widget, and integration test layers in detail. If UI code depends on material_ui widgets at the state layer, the separation in our Flutter state management with Riverpod guide helps keep this kind of SDK change from leaking into state logic.
Running flutter analyze in CI is the cheapest way to catch forgotten old imports. Firebase-integrated projects may see an extra dependency chain here — check the compatibility notes in our Flutter Firebase integration guide.
GOLDEN TIP
The most valuable insight in this article
This tip holds the article's most important takeaway.
Easter Egg
You found a hidden gem!
There's a hidden detail in this section. Want to uncover it?
Reader Reward
If you want to turn this migration process into a lasting reference, you can copy the items below into your own migration checklist file. The list is a compressed version of the steps covered in the article, prepared as plain text so it can be pasted directly into your team's PR template.
FAQ
What is the material_ui package in Flutter 3.47?
material_ui is the independently versioned pub.dev version of the package:flutter/material.dart library, previously bundled into the Flutter SDK, now moved to the flutter/packages repository. It reached version 1.0 with Flutter 3.47 (August 12, 2026), and can now be updated weekly, independent of the SDK's quarterly release cycle.
How do you migrate to material_ui 1.0?
Run dart fix --apply --code=migrate_design_widgets in your terminal; this command replaces package:flutter/material.dart and package:flutter/cupertino.dart imports with the new packages and attempts to add the dependencies to pubspec.yaml. If the pubspec update fails, manually run flutter pub add material_ui (and cupertino_ui if needed), then re-run dart fix --apply.
Are Cupertino widgets being removed from the SDK?
Not for now — the migration is optional, and the old libraries inside the SDK still work completely fine in Flutter 3.47. They're only planned to formally enter deprecation in the upcoming "Fall stable" release this November; the exact removal date hasn't been clarified in these sources, and this point remains uncertain.
What does MaterialUiCompatibilityBridge do?
If part of your project has moved to material_ui but you still have third-party packages depending on the old package:flutter/material.dart, MaterialUiCompatibilityBridge is a transitional layer that lets these two widget trees share the same ThemeData and MaterialLocalizations so they can run at the same time. It's used by wrapping it inside MaterialApp.builder or applying it only to the relevant subtree; it's recommended to remove it once all dependencies have migrated.
Do I need to remove the flutter_localizations package from pubspec?
No, it isn't required. flutter_localizations isn't deprecated; what's changed is that the localization delegates specific to Material and Cupertino are now also available inside material_ui/cupertino_ui. In a fully migrated project you can remove the package, but leaving it in won't break anything — as long as you're getting the delegates via material_ui/cupertino_ui.
What happens if I don't migrate?
As of August 15, 2026, nothing breaks; the old imports keep working. However, after the official deprecation announcement in November, you're likely to run into compiler warnings and, later, be forced into an unplanned migration if the in-SDK libraries get removed — which is why it's safer to complete the migration mechanically now.
Conclusion
Flutter 3.47's material_ui/cupertino_ui split is, for most projects, a migration that starts with a single command but calls for careful verification. Start with dart fix --apply --code=migrate_design_widgets, keep flutter pub add ready for the pubspec bug, rely on MaterialUiCompatibilityBridge for tangled dependency trees, and simplify localization with GlobalMaterialLocalizations.delegates. Find the parallel rendering-engine changes in our Impeller rendering engine guide, architectural prep in our Flutter Clean Architecture guide, and test verification in our Flutter testing guide. The November timeline gives no hard date, but it creates pressure — doing this now, in a controlled way, beats a rushed migration later.
Sources
- What's new in Flutter 3.47 — The Flutter Blog — official announcement: material_ui/cupertino_ui 1.0, migration command, deprecation timeline
- material_ui | Flutter package — pub.dev — official package page, README, and code samples
- cupertino_ui | Flutter package — pub.dev — official standalone Cupertino design library package
- How to Work with Material and Cupertino Decoupling in Flutter — freeCodeCamp — step-by-step migration handbook
- flutter/flutter Issue #188757 — flutter_localizations with material_ui/cupertino_ui — pre-1.0 discussion of a localization incompatibility (closed July 15, 2026)
- Flutter 3.47: Material and Cupertino Become Standalone Packages — daily.dev — summary news source
- Flutter 3.47 Upgrade Readiness Checklist — Dopebase — third-party compatibility checklist
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
We respect your privacy. You can unsubscribe at any time.

