Flutter’s design system libraries have always been part of the core SDK. When you imported package:flutter/material.dart, you were pulling in widgets, themes, and components that shipped as part of the Flutter runtime itself. Updating them meant waiting for a Flutter SDK release.
Flutter 3.47, released in August 2026, reached a milestone that changes this: the standalone material_ui and cupertino_ui packages graduated to 1.0. The design systems can now ship independently of the Flutter SDK.
This is an architectural decision with practical consequences for every Flutter project, and the Flutter team is clear about the direction: the bundled libraries in the core SDK will eventually be deprecated. Understanding what the decoupling actually changes — and what it does not — helps teams decide when and how to move.
What the standalone packages are
The material_ui and cupertino_ui packages are direct replacements for package:flutter/material.dart and package:flutter/cupertino.dart. They expose the same widgets — MaterialApp, Scaffold, CupertinoNavigationBar, CupertinoButton — through an independent Pub package that can be versioned and updated separately from the Flutter SDK.
Installing them is a pubspec.yaml change:
dependencies:
flutter:
sdk: flutter
# Replace the bundled import with the standalone package
material_ui: ^1.0.0
# or
cupertino_ui: ^1.0.0
In source files, the import paths change:
// Before
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
// After
import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';
The API surface at 1.0 is intentionally compatible with the bundled versions. A migration for a typical app should not require widget-level changes — it is a dependency and import change, not a redesign.
Why this matters operationally
Design system updates without a Flutter SDK upgrade. Previously, a bugfix in Checkbox or a new NavigationDrawer variant required waiting for the next Flutter stable release. With standalone packages, the Flutter team can push design system updates on their own cadence. This is a meaningful benefit for teams working on products with tight release windows who could not always adopt a new Flutter SDK immediately.
Impeller is now the default renderer on desktop. Flutter 3.47 also shipped Impeller as the default renderer on macOS, Windows, and Linux. This is relevant because Impeller pre-compiles shaders during the build, eliminating the “jank on first render” that users experienced with the legacy Skia renderer, which compiled shaders at runtime. Apps that ship to desktop targets will see smoother animations without code changes — the renderer change is automatic.
Widget Previews graduated to stable. The Widget Previews tool is now stable, with local build caching and real-time search for finding components. For teams maintaining large widget libraries, the workflow change is substantial: you can preview components in isolation without launching the full application.
Migration path for existing projects
For a project currently using the bundled package:flutter/material.dart, the migration is lower-urgency than it may appear. The bundled libraries remain available; deprecation has not been announced with a removal timeline. The 1.0 release of the standalone packages marks stability, not an immediate sunset of the bundled ones.
A reasonable migration plan:
- New projects: Start with the standalone packages. There is no reason to use the bundled version for a project that does not exist yet.
- Existing projects with a next major release: Include the migration in the next release cycle as a dependency change. Validate the import paths compile cleanly and run the full test suite.
- Large projects with extensive custom theming: Audit whether any widget subclasses reach into internal implementation details that the standalone packages may have reorganised. This is the one area where compatibility shims may be needed.
The migration tooling in dart fix does not yet automate the import path changes as of 3.47. A codebase-wide search-and-replace for the import strings is the practical approach for large codebases:
# Dry run to count affected files
grep -rl "package:flutter/material.dart" lib/ | wc -l
# In-place replacement
find lib -name "*.dart" -exec sed -i '' \
's|package:flutter/material.dart|package:material_ui/material_ui.dart|g' {} \;
After the replacement, flutter analyze will surface any API differences. Most codebases will have zero issues; those with widget subclasses should review the standalone package’s changelog for internal API changes.
What this does not change
The core package:flutter/widgets.dart — the widget layer below Material and Cupertino — remains part of the Flutter SDK. StatelessWidget, StatefulWidget, BuildContext, InheritedWidget, and the rest of the primitive widget surface are not moving to standalone packages. Only the design system implementations (Material Design and Apple’s Human Interface Guidelines layer) are decoupling.
Custom design systems built directly on the widget layer are unaffected by this migration entirely. If your team maintains an internal design system that wraps Flutter primitives rather than extending Material, the 1.0 announcement is relevant for dependency management but has no migration cost.
The practical summary
The material_ui 1.0 milestone is a useful operational improvement for teams that want design system updates between Flutter SDK releases. The migration for existing apps is straightforward and non-urgent. The more immediately useful change in Flutter 3.47 for existing apps is Impeller on desktop, which requires no migration at all.
For new Flutter projects in 2026, starting with the standalone packages is the right default. The trajectory of the ecosystem is clearly toward them, and there is no cost to adopting them from day one.