What’s new in Flutter 3.10
Seamless web and mobile integration, breakthrough graphics performance via Impeller in stable, and more
Welcome to Flutter 3.10! We can’t wait to show off the huge efforts of our amazing Flutter community. This Flutter release runs the incredible Dart 3 also available today!
Flutter 3.10 includes many improvements to web, mobile, graphics, security and so much more. Let’s get down to business!
The Material library now matches the latest Material Design spec. Changes include new components and component themes, updated component visuals and more. Developers must “opt in” to these changes using the
useMaterial3 theme flag. In the next stable release,
useMaterial3 defaults to
To opt in to the M3 version of the Material library, set
useMaterial3 : true in your
MaterialApp theme. The
flutter create command adds this to your theme when creating a new app.
To preview these changes, check out the demo app. The demo lets you toggle
useMaterial3 on and off.
All M3 components configure the default colors of the theme’s
ColorScheme. The default color scheme uses shades of purple. You can create a custom color scheme either from a single “seed” color or from an image. Try both variations with the demo. Color schemes generated should look good and be accessible.
This provides an M3 version of
BottomNavigationBar widget. While M3 uses different colors, highlighting, and elevation, it works as it did before. To override the default appearance of the
NavigationBars widget, use the
NavigationBarTheme widget. Though you don’t need to migrate existing apps to this component, you should use it for new apps.
This provides an M3 destination selection widget based on the Drawer widget.
NavigationDrawer shows a single-selection list of
NavigationDestinations widgets. You can include other widgets in this list as well. The
NavigationDrawer can scroll when needed. To override the default appearance of the
NavigationDrawers widget, use the
SearchBar and SearchAnchor
These components provide predictive text for search queries. When the user enters a search query, the app computes a list of matching responses in a “search view”. The user either selects one or adjusts the query. To override the M3 design of these components, use the
Secondary Tab Bar
M3 allows you to create a second tier of tabbed content. To distinguish this second
DatePicker updated for M3
DatePicker updates the colors, layout, and shape for both the calendar and textfield versions of the widget. This doesn’t change the API, but adds a new
TimePicker updated for M3
TimePicker, like the
DatePicker, updates the colors, layout, and shapes for both the regular and compact versions of the widget.
BottomSheet updated for M3
Beyond M3 color and shape updates, the bottom sheet now adds an optional drag handle that’s included when you set
ListTile updated for M3
ListTile updates positioning and spacing of this widget. This includes content padding, leading and trailing widget alignment, minimum leading width, and vertical spacing. The API remains unchanged.
Drawer updated for M3
Drawer updates the colors and elevation while making some small layout changes.
M3 updates all
TextField widgets to support native gestures. Double clicking or triple clicking with a mouse work the same as double tapping or triple tapping on a touch device. By default, the
CupertinoTextField widgets use these features.
TextField double click/tap gestures
- Double click + drag: Extends the selection in word blocks.
- Double tap + drag: Extends the selection in word blocks.
TextField triple click/tap gestures
- Selects a paragraph block at the clicked position when inside of a multi-line
- Selects a line block at the clicked position when inside of a multi-line
- Selects all text in a single-line
- Selects a paragraph block at the clicked position when inside of a multi-line
- Selects all text in a single-line
Triple click + drag
- Extends the selection in paragraph blocks (Android/Fuchsia/iOS/macOS/Windows).
- Extends the selection in line blocks (Linux).
Flutter supports SLSA level 1
Flutter Framework now compiles with Supply Chain Levels for Software Artifacts (SLSA) Level 1. This acknowledges the implementation of many security features including:
- Scripted build process. The build scripts for Flutter now allow automated builds on trusted build platforms. Building on protected architecture helps prevent artifact tampering which improves supply chain security.
- Multi-party approval with audit logging. Flutter release workflows execute only after multiple engineers approve. All executions create auditable log records. These changes ensure that no one can introduce changes between source code and artifact generation.
- Provenance. Beta and stable releases now build with provenance. This means trusted sources with expected contents built the framework release artifacts. Each release publishes links to view and verify provenance on the SDK archive.
This work also allows the team to advance toward SLSA L2 and L3 compliance. These two levels focus on protecting artifacts during and after the build process.
Flutter web apps improved load times
This release reduces the file size of icon fonts. It pruned unused glyphs from both Material and Cupertino.
CanvasKit reduced size for all browsers
Chromium-based browsers can use an even smaller custom CanvasKit “flavor”. The hosted CanvasKit serves from Google’s industry-leading CDN. This should improve performance further.
You can now serve Flutter web apps from a specific element in a page. Before this release, your apps could either fill the entire page body or display within an
iframe tag. Sample code can be found in GitHub.
Web apps can use Flutter’s fragment shader support.
In the 3.7 stable release, we previewed Impeller on iOS. Since then, we received and addressed a lot of great feedback from users. With over 250 commits to Impeller in this release, we set Impeller as our default renderer on iOS. By default, all apps built for iOS with Flutter 3.10 use Impeller. These iOS apps will have less jank and better consistent performance.
Since the 3.7 release, Impeller on iOS has improved its memory footprint. Impeller uses fewer render passes and intermediate render targets. On newer iPhones, enabling lossy texture compression reduced memory footprint without affecting fidelity. These advances also made a marked improvement in performance on iPads.
Consider a complex screen like the “pull quote” screen in the Wonderous app. Together, these improvements cut the memory footprint of those screens almost in half. The reduction in memory usage also gives a modest drop in GPU and CPU load. The Wondrous app may not register that drop in load. Its frames had rendered under budget before, but this change should extend battery life.
Impeller also unlocks the team’s ability to deliver popular feature requests faster. One example results in support for the wider P3 color gamut on iOS. Look elsewhere in this post for a description of that feature.
Community contributions accelerated our progress, in particular GitHub users ColdPaleLight and luckysmg. They authored several Impeller-related patches that improved fidelity and performance.
While Impeller meets the rendering needs of most Flutter apps, you can opt-out of Impeller. If you choose to opt-out, consider filing an issue on GitHub to tell us why. App users may notice that Skia and Impeller render with minor differences. These differences could be bugs, so don’t hesitate to file issues. In a future release, we will remove the legacy Skia renderer for iOS to reduce Flutter’s size.
Progress continues on a Vulkan backend for Impeller. Impeller on Android remains under active development but not ready for preview. We plan to share more about it in the near future.
To follow along with our progress, check out our GitHub project board.
This release covers more performance improvements and fixes aside from Impeller.
We want to thank open-source contributor luckysmg. They discovered they could slash the time to get the next drawable layer from the Metal driver. To get that bonus, you need to set the
FlutterViews background color to a non-nil value. This change eliminates low frame rates on recent iOS 120Hz displays. In some cases, it triples the frame rate. This helped us close over half a dozen GitHub issues. This change held such significance that we backported a hotfix into the 3.7 release.
In the 3.7 stable release, we shifted loading of local images from the platform thread to the Dart thread to avoid delaying vsync events from the platform thread. However, users noticed that this additional work on the Dart thread also caused some jank. In this release, we moved the opening and decoding of local images from the Dart thread to a background thread. This change eliminates potential long pauses on screens with a lot of local images, while avoiding delaying vsync events. In our local testing and automated benchmarks, this change cut the load time for several simultaneous images in half.
We continue to build optimizations on top of Flutter’s new internal DisplayList structure. In this release, we added an R-Tree based culling mechanism. This mechanism removes the processing of drawing operations much earlier in our renderer. This optimization accelerates, for example, a custom painter whose output fails offscreen. Our microbenchmarks showed a decreased DisplayList processing time of up to 50%. Apps with clipped custom paints could see differing improvements. The degree of improvement depends on the complexity and number of hidden draw operations.
Reducing iOS startup latency
An inefficient strategy for identifier lookups in app bundles increased app startup latency. This startup latency grows in proportion to the app’s size. In this release, we fixed the bundle identifier lookup. This reduced startup latency by 100ms or about 30–50% in a large production application.
SkParagraph as the default library for text shaping, layout, and rendering. We included a flag to fall back on the legacy
minikin libraries. As we have full confidence in
SkParagraph, we removed
minikin and their flag in this release. This reduces Flutter’s compressed size by 30KB.
In the 3.0 release, we enabled an Android feature late in our rendering pipeline. This Android feature used advanced GPU driver features. These driver features repaint less of the screen when only one “dirty” region changes. We added this to earlier optimizations to our graphics pipeline with similar effects. Though our benchmarks results encouraged us, two issues surfaced. First, the most improved benchmark might not represent practical use cases. Second, the set of devices and Android versions that supported this GPU driver feature proved hard to find. Given the limited advances and support, we disabled the partial repaint feature on Android.
The feature remains enabled on iOS when using the Skia backend. We expect to enable it with Impeller in a future release.
Flutter 3.10 addresses one of our most promoted issues. It adds the ability to decode
APNG images. You can load
APNG images with Flutter’s existing image loading APIs.
Image loading API improvements
Flutter’s esteemed Director of Engineering tvolkert has landed improvements to
dart:ui’s image loading APIs. We have added a new method
instantiateImageCodecWithSize. This supports the use case of loading an image that meets these three conditions:
- an aspect ratio unknown at load time
- a bounding box constraint
- an original aspect ratio constraint
An example would be when an app tries to display one image from a pool of possibilities loaded from the network.
You can now run and hot reload your Flutter iOS apps without a cable! After a successful wireless pairing of your iOS device in Xcode, you can deploy your app to that device using flutter run. If you encounter issues, verify the network icon appears next to your device under Window > Devices and Simulators > Devices. To learn more, check out our documentation.
Wide gamut image support
Flutter apps on iOS can now support accurate rendering for wide gamut images. To use wide gamut support, the app must use Impeller and add the
FLTEnableWideGamut flag in the
SpellCheckConfiguration() widget now defaults to supporting Apple’s spell check service on iOS. To use this widget, set it using the
spellCheckConfiguration parameter in
Adaptive checkbox and radio
This release adds the
CupertinoRadio widgets to the
Cupertino library. They create checkbox and radio button components that match Apple’s styling.
The Material checkbox and radio widgets added the
.adaptive constructors. On iOS and macOS, these constructors use the corresponding Cupertino widgets. On other platforms, they use Material widgets.
Refining Cupertino animations, transitions and colors
Flutter 3.10 improved some animations, transitions, and colors to match SwiftUI. These improvements include:
- Updating the
- Adding a title magnification animation to
- Adding several new iOS system colors to
PlatformViews appear on screen, Flutter throttles the refresh rate on iOS to reduce jank. App users will notice this when the app displays animated or scrollable
macOS and iOS can use shared code in plugins
Flutter now supports the
sharedDarwinSource key in the
pubspec.yaml file for plugins. This key indicates that Flutter should share iOS and macOS code.
New resources for app extensions
We added documentation for Flutter developers to use iOS app extensions. These extensions include live activities, home screen widgets, and share extensions.
To simplify creating home screen widgets and sharing data, we added new methods to the
New resources for cross-platform design
The documentation now includes cross platform design considerations for specific UI components. To learn more about each of these UI components, check out the discussions in the Flutter UX GitHub repository. We appreciate any input or feedback!
Android CameraX support
Camera X, a Jetpack library, simplifies adding rich camera functionality to your Android app. This functionality applies across a wide selection of Android Camera hardware. With this release, we add preliminary support for CameraX to the Flutter Camera plugin. This support covers the following use cases:
- Image Capture
- Video Recording
- Display live camera preview
To give it a try, opt in to using the CameraX implementation. To opt in, add the following line to your
camera: ^0.10.4 # Latest camera version
We would love your feedback as we continue to add more CameraX features then make CameraX the default implementation.
We continue to improve DevTools, the suite of performance and debugging tools for Dart and Flutter. Some highlights include:
- The DevTools UI uses Material 3. This both modernizes the look and enhances accessibility.
- The DevTools console supports evaluations for a running app in debug mode. Before this release, you could only do this when you paused an app.
- An embedded Perfetto trace viewer replaces the previous timeline trace viewer. Perfetto handles larger datasets and performs better than the legacy trace viewer. Perfetto includes more features, such as:
- Allowing you to pin threads of interest.
- Clicking and dragging to select multiple timeline events from multiple frames.
- Using SQL queries to pull specific data from the timeline events.
To learn more, check out the release notes for DevTools 2.23.1, DevTools 2.22.2, and DevTools 2.21.1.
Deprecations & Breaking Changes
Breaking changes in this release include deprecated APIs that expired after the release of v3.7. To see all affected APIs, along with additional context and migration guidance, check out the deprecation guide for this release. Dart Fix can remedy many of these issues, including quick fixes in the IDE and bulk apply with the
dart fix command.
Android Studio Flamingo upgrade
After you upgrade Android Studio to Flamingo, you might see an error when you try to flutter run or flutter build your Flutter Android apps. This error occurs because Android Studio Flamingo updates its bundled Java SDK from 11 to 17. Gradle versions earlier than 7.3 can’t run when using Java 17. We updated
flutter analyze --suggestions to validate if this error occurs due to incompatibility between your Java SDK and your Gradle version.
To learn different ways to fix this error, check out our migration guide.
Window singleton deprecation
This release deprecates the window singleton. Apps and libraries relying on it should migrate away from it. This prepares your app for multi-window support when it launches in a future version of Flutter.
Thanks to the community
As always, many thanks to the community for contributing tests, they help us identify these breaking changes. To learn more, check out our breaking change policy.
Wrapping it up
As we wrap up this release, the Flutter team at Google wants to thank all the contributors who have made this release possible. Your dedication and hard work have helped to make Flutter a game-changer in the industry and continue to revolutionize application development. We encourage you to start exploring this latest stable version of Flutter to take advantage of all the amazing features it has to offer. To do so, just
flutter upgrade! Stay tuned for more exciting updates from Flutter in the future.