Flutter 3.50: What It Changes for Teams Shipping Real Products
Stable native interop, Material moving out of the SDK, stricter Android security and a deadline for CocoaPods. A product engineering reading of what Flutter 3.50 means for the apps you build, maintain and pay for over years, not weeks.
Framework releases usually get judged in the week they ship: what's new, what's faster, what's worth trying on a Friday afternoon. Teams that build and maintain products end up judging them later, and by a different measure. What will this release cost us to adopt? What will it cost us not to adopt? Which decisions we made two years ago does it reward, and which does it quietly penalise?
That second measure is the one we've applied to Flutter 3.50. By the first, it's a solid release with a respectable list of features. By the second, it's one of the more consequential Flutter releases in some time, because most of its weight sits in decisions about what the framework will stop doing for you.
In a single cycle, the Flutter team has deprecated the Material and Cupertino libraries that ship inside the SDK, made direct native interop stable, drawn a firm line under the old JavaScript interop libraries, attached a deadline to CocoaPods, begun retiring Intel Macs as build machines, and stopped Android release builds from trusting what other apps pass in through an Intent. Each change is reasonable on its own. Together, they move a meaningful share of responsibility from the framework to the teams building on it: responsibility for dependencies, for native code, for release testing and for upgrade planning.
For a new product, that shift is mostly good news. For a mature app carrying years of plugins and platform workarounds, it's a planning exercise that deserves to be scheduled rather than discovered.
In short
- Native integrations get cheaper. FFIgen and JNIgen are stable, so plugins can call platform APIs directly instead of through asynchronous platform channels.
- Your design system becomes a dependency.
package:flutter/material.dartandpackage:flutter/cupertino.dartare deprecated in favour of the standalonematerial_uiandcupertino_uipackages. - Android release builds are stricter than debug builds. Exported Flutter activities now ignore unverified routing and engine extras, but only in release mode.
- Apple platforms come with deadlines. CocoaPods trunk goes read-only in December 2026, and Intel Macs are on their way out as build hosts.
- Flutter web gets operational tooling. Opt-in Wasm on Safari and Firefox, built-in content hashing, and a build flag that finds legacy JS interop.
- Most of the upgrade risk lives in your plugins, not in your own code.
Where 3.50 sits in Flutter's year
Flutter 3.50 reached the stable channel on 11 November 2026, alongside Dart 3.14. The official announcement credits 188 contributors, 69 of them first-timers, with more than 1,200 commits. (Flutter blog)
It's also the last of four releases Flutter scheduled in public at the start of the year. Flutter 3.41 introduced published release windows with fixed branch cut-off dates, and 3.50 was always pencilled in for November. (Flutter 3.41 announcement) That predictability is easy to undervalue. For anyone who plans engineering work against a product roadmap, knowing when the platform will move is almost as useful as knowing what it will do.
The bigger context is what came earlier in the year. Flutter 3.44 made Swift Package Manager the default on Apple platforms and began freezing the in-SDK design libraries. Flutter 3.47 published material_ui and cupertino_ui as standalone 1.0 packages and made Impeller the default renderer on macOS, Windows and Linux. (Flutter 3.47 announcement) Much of 3.50 is those threads being pulled tight. Things that were available earlier in the year are now expected, and several warnings have become deprecations.
This article covers the Flutter side of the release. Dart 3.14 has its own changelog, which is worth reading separately if your team follows language and tooling changes closely.
Native integrations: cheaper to build, still yours to own
Ask any team that has estimated a cross-platform product where the estimate went wrong, and native integration will be near the top of the list. Payments, media, mapping, Bluetooth, a partner's proprietary SDK: the moment a product needs something the framework doesn't expose, the cost of a "single codebase" goes up.
Flutter 3.50 lowers that cost. FFIgen (for C and Objective-C) and JNIgen (for Java and Kotlin) are now stable, and Pigeon has a native interop mode in preview that uses both generators to produce type-safe bindings. (Flutter blog)
Until now, Flutter has talked to the host platform through platform channels, an asynchronous message bus. Dart serialises a call, the engine passes it across, Kotlin or Swift decodes it, does the work, encodes a reply and sends it back. Every call is asynchronous even when the underlying OS API isn't, every value crosses a codec, and plugin authors write glue code in three languages for each method they expose.
Generated bindings remove the bus. Dart calls the native API directly, the call can be synchronous, and it can run on a background isolate rather than being routed through the main one. That changes more than performance. The "everything returns a Future" constraint has shaped a decade of plugin APIs; a plugin reading a value the OS already holds in memory still had to make you await it. With direct bindings, a plugin's Dart API can finally look like the native API it wraps.
The official guidance is deliberately cautious, and we think rightly so. Flutter's interop documentation still recommends Pigeon as the default for plugins, and warns that working with FFIgen and JNIgen directly brings threading and memory-management responsibilities that Pigeon's generated code handles for you. (Flutter interop docs) Pigeon's native interop mode also doesn't cover Windows or Linux, where platform channels remain the route. (Pigeon docs)
Adoption is already under way among teams with the most to gain. Nutrient, which ships a commercial PDF SDK for Flutter, has written publicly about rebuilding its Flutter layer on JNIgen and FFIgen bindings during 2026. (Nutrient engineering blog)
For a product team, the practical implications are threefold. First, the plugins you depend on will start migrating, and some will change shape: an API that returned a Future may become synchronous, which is a breaking change you'll inherit through a version bump. Second, if your product relies on a native SDK that has no good Flutter plugin, building one in-house has become a more realistic option. Third, generated bindings are still native code your team owns. They need someone who understands the platform's threading model, and they deserve the same review and test coverage as anything written by hand.
Your design system now has its own version number
For most of Flutter's life, import 'package:flutter/material.dart'; has been the first line of nearly every widget file. In 3.50, that import, its Cupertino counterpart and the related flutter_localizations delegates are formally deprecated, and flutter create now generates projects that import package:material_ui instead. (Flutter blog)
From an engineering point of view, this is a migration. From a product design point of view, it's a change in who controls the pace of your interface.
When the design libraries shipped inside the SDK, they moved with it. A fix to a Material component waited for the next quarterly release, and upgrading Flutter for an unrelated reason (a new iOS SDK requirement, say) also changed your buttons, text fields and dialogs, whether or not design had signed off. Now the design system has its own version number. The breaking-changes index already lists one change that arrived through material_ui 1.8.0 rather than through Flutter itself: DropdownButtonFormField gained an explicit enabled property, and onChanged became optional. (Breaking changes index) Components now evolve on their own clock.
That matters most for products with a custom design system, which is to say most serious products. Very few ship stock Material; they build a branded component layer on top of it. With Material as a pinned dependency, that layer gains a proper upstream. Design and engineering can take a platform upgrade for a security or OS fix without also accepting visual changes, then move the design library deliberately, on a schedule that fits design review and visual regression testing.
The mechanical part of the migration is small. The official guide adds the packages first and then rewrites imports, with a dart fix code to automate the rewrite. (Migration guide)
flutter pub add material_ui
flutter pub add cupertino_ui
dart fix --apply --code=migrate_design_widgets// 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';Localization delegates need a manual pass, and that's the step most likely to slip through in an app with many locales.
The harder part is the dependency tree. Your own code can move in an afternoon; a third-party widget package that still imports the SDK copy of Material is outside your control. For apps that lean on UI kits, the real work is an audit of which dependencies have shipped material_ui support and which haven't. Deprecated is not removed, and existing imports still compile in 3.50. But a deprecation warning is the start of a runway, and runways end.
Flutter web: fewer workarounds to maintain
Flutter web has long been the platform that needed the most caveats in a technical proposal. This release removes several of them, mostly by giving teams better tools rather than by changing defaults.
Cache-busting is now part of the tool. Every team that has deployed Flutter web behind a CDN has met the stale-bundle problem: a browser holding yesterday's main.dart.js against today's index.html. The new --web-content-hash flag fingerprints JavaScript, Wasm and asset filenames, updates flutter_bootstrap.js to reference them, and emits a precache_manifest.json for teams running their own service worker or Workbox setup. The accompanying guidance is the standard one: cache hashed bundles for a year, and serve index.html and flutter_bootstrap.js with no-cache. The older flutter_service_worker.js token approach is deprecated. (Flutter blog) For many teams, this deletes a custom script from the deployment pipeline, and every script you delete is one fewer thing to maintain.
WebAssembly beyond Chromium. flutter build web --wasm already produced a Wasm build with a JavaScript fallback, and Chrome and Edge 137+ already ran it. In 3.50, Safari 26.2+ and Firefox 147+ can be opted in through a wasmAllowList setting in web/flutter_bootstrap.js. Google reports more than double the frame rate of the JavaScript build on heavy widget benchmarks in those browsers. Those are Google's numbers, and real gains will depend on how much of your app is rebuild-bound, so treat them as a reason to measure rather than a result to expect. The team has said it intends to make Wasm the default on Safari and Firefox in a future stable release.
A firm line under legacy JS interop. dart:html, dart:js, dart:js_util and package:js are deprecated in favour of dart:js_interop and package:web, and are slated for removal in a future Dart release. A new --no-deprecated-js-interop flag, accepted by flutter build web, flutter run and flutter test --platform chrome, fails the build if any legacy import remains. For web teams, it's the most useful flag in the release: it tells you which dependencies are blocking a Wasm build before a removal deadline does.
# Fail if any legacy JS interop import remains (yours or a dependency's)
flutter build web --no-deprecated-js-interop
# Fingerprint JS, Wasm and asset filenames for long-lived caching
flutter build web --web-content-hashAn experimental preview called WebParagraph, built with the Chrome team on the experimental Enhanced TextMetrics API, lets the browser shape text with system fonts. The reported effect is a CanvasKit download that shrinks from about 5.46 MB to about 3.75 MB, with fewer missing-glyph boxes and native colour emoji. It depends on a browser API that is itself experimental, so it's one to follow, not one to ship. One behavioural change is worth checking now: when a page sets viewport-fit=cover on mobile browsers, SafeArea now respects notches and home indicators. (Breaking change note) If you were padding around them by hand, you may now be padding twice.
None of this changes the fundamental question of where Flutter web fits. It still renders to a canvas, text remains the area where its seams show, and it's still a poor fit for content-led sites that depend on search visibility. For app-like products such as dashboards, internal tools, editors and authenticated experiences, it keeps getting stronger. For marketing sites and content-heavy pages, a framework built for the document web, such as Next.js, remains the better choice.
Android: a security fix you'll only see in release builds
The Android change with the widest reach is a security fix, and it's easy to miss because it only takes effect in release builds.
Flutter's Android embedder has long honoured a set of Intent extras: an initial route, a Dart entrypoint and its arguments, and the IDs of a cached engine or engine group. Until now, any caller could set them. If your FlutterActivity was exported, another app on the device could open it at an internal route, choose which Dart entrypoint ran, or attach to a warm engine that might already hold an authenticated session. In 3.50, FlutterActivity and FlutterFragmentActivity verify the sender before honouring those extras. In release builds, unverified extras are ignored, and the embedder falls back to manifest metadata or defaults. (Breaking change guide)
You're only affected if you pass one of those extras and the target activity is exported, either explicitly or through an intent filter. The risk for product teams is in testing. Debug and profile builds bypass the verification and only log a warning, so adb and automated tests keep working. A notification that opens a specific screen through EXTRA_INITIAL_ROUTE can pass every QA build and then open the home screen in production.
The migration guide offers several fixes. The simplest is to stop exporting activities that no external app needs to open:
<activity
android:name=".CheckoutFlutterActivity"
android:exported="false" />For navigation from outside the app, the recommended route is a proper deep link with a matching <intent-filter>. Static entrypoints and routes can move into <meta-data> in the manifest, and dynamic configuration can move into overrides on an activity subclass. On Android 13 and below, internal launches of an exported activity should use startActivityForResult() so the calling package can be verified. Release builds also now reject runtime engine flags. (Release-mode engine flags note)
The Android toolchain has moved as well. According to the release notes, the minimum Android Gradle Plugin version is now 9.1.1, and new projects start on AGP 9.3.1, Gradle 9.5.0 and Java 17, with minSdkVersion 24 and compile and target SDK 36. More significant for the ecosystem, plugins are expected to move to AGP's built-in Kotlin support; plugins that still apply the Kotlin Gradle Plugin themselves will receive lower pub.dev scores and will fail under AGP 10. (Flutter blog; release notes) For an app team, that's not a code change but a plugin audit with a deadline.
Hybrid Composition++, the newer way of embedding native Android views, receives further fixes. It's still opt-in on stable (flutter config --enable-hcpp), requires Android 14 (API 34) or later with Impeller on Vulkan, and is already on by default in the beta channel. Products that rely on maps, web views or video players as platform views should start testing it before it becomes the default.
Apple platforms: a frame faster, and two deadlines
The best iOS change in 3.50 needs no code. A rework of how the engine delivers touch events hands them to the framework immediately rather than holding them for the next frame. Google puts the saving at roughly 16 ms on 60 Hz displays and 8 ms on 120 Hz ProMotion screens, measured on devices going back to the iPhone 6s. (Flutter blog)
One frame sounds small. It isn't for the interactions people use to judge whether an app feels native: dragging a list, scrubbing a timeline, drawing with a finger. Input latency is one of the few performance problems users perceive directly without being able to name it. A free frame of responsiveness is exactly the kind of improvement that never appears in a product changelog yet shows up in how reviews describe the app.
The rest of the Apple story is about dates. CocoaPods trunk becomes read-only in December 2026. Flutter now warns on every CLI command when Swift Package Manager is disabled, and a future release will remove both the opt-out and the CocoaPods fallback. Any iOS or macOS plugin in your tree without SPM support is now a scheduled problem.
Intel Macs are on a similar clock. Flutter no longer tests on them, the CLI warns when it runs on one, and future releases will require Apple Silicon to build iOS, macOS and Android apps. That last detail is easy to miss: if your CI includes Intel macOS runners that also produce Android builds, they need replacing too. Teams can opt into Apple Silicon-only macOS builds today with flutter config --enable-macos-arm64-only.
For teams building against Xcode 27, 3.50 also fixes several debugging problems: newly paired devices are prepared automatically, intermittent launch crashes in flutter run are resolved, and flutter screenshot works on physical devices again. It's worth remembering the larger Xcode 27 requirement that arrived with Flutter 3.47: apps built with the iOS 27 SDK must adopt the UIScene lifecycle or they won't launch. Flutter migrates unmodified projects automatically, but apps with custom native code in their AppDelegate need manual changes. (Flutter 3.47 announcement; UIScene adoption guide)
Smaller changes worth a line in your backlog
Not everything in 3.50 is strategic. A handful of framework changes will quietly remove workarounds from a mature codebase. SliverClipRect and SliverClipRRect can clip a scrolling section without cutting into a pinned header. ListView.separated gains itemExtentBuilder, so long variable-height lists with dividers no longer need offscreen builds to measure rows. showDialog accepts a barrierBuilder for custom backdrops, and TextInputType.numberWithOptions gains a password option for secure PIN entry.
Accessibility gets two useful additions: a dedicated SemanticsRole.slider, and a reduceMotion preference on MediaQueryData, alongside the existing disableAnimations. Respecting it costs very little:
@override
Widget build(BuildContext context) {
final reduceMotion = MediaQuery.of(context).reduceMotion;
return AnimatedSwitcher(
duration: reduceMotion
? Duration.zero
: const Duration(milliseconds: 250),
child: child,
);
}Two text changes alter existing behaviour and belong on your regression list: soft hyphens now render a visible hyphen when a word wraps at them, and WidgetSpans in right-to-left text now follow natural reading order. (Breaking changes index) Localised strings and RTL layouts with inline icons are exactly where golden tests earn their keep. On desktop, multi-window support (developed with Canonical) remains experimental, and its API is still changing: RegularWindow is now Window, and sizedToContent has become shrinkWrap.
Beyond the release notes
Release notes describe changes one at a time. The useful questions are about what they add up to for the people who decide what to build, how to build it and what to spend on keeping it healthy.
For product decisions
Choosing a technology for a new product. Two long-standing objections to Flutter get weaker in this release. The cost of reaching native functionality falls with stable direct interop, which makes Flutter a more credible choice for products with deep hardware or third-party SDK requirements. And the design system's independence from the SDK makes it easier to maintain a strongly branded interface over time. The objections that remain are mostly about the web: for content-led products where search visibility and document semantics matter, Flutter is still not the natural fit.
Balancing speed with long-term flexibility. Flutter's early-stage speed hasn't changed, and that was never really the issue. What 3.50 changes is the cost of staying flexible later. A product that starts on material_ui, SPM and current Android tooling begins with no migration debt. A product that defers these changes is not standing still; it's accruing work that will come due at an inconvenient moment, usually alongside an Apple or Google platform deadline.
Decisions that support product evolution. Predictable release windows, explicit deprecations and published future plans make it possible to plan platform work the way you'd plan features. That's a real improvement for product planning, provided someone on the team is reading the signals.
For engineering
Architecture. The two areas where Flutter is changing fastest, native integration and the design layer, are also the two areas where clean boundaries pay off most. If your app code talks to platform capabilities through your own interfaces rather than calling plugins directly, a plugin's move from platform channels to generated bindings becomes a change inside one adapter rather than a change spread across the codebase:
/// App code depends on this interface, never on a specific plugin.
abstract interface class SecureStore {
Future<String?> read(String key);
Future<void> write(String key, String value);
}The same principle applies to design: a product component layer that wraps Material contains the impact of a material_ui upgrade to one package rather than every screen.
Plugin and dependency management. Look at the list of migrations in this release: built-in Kotlin, Swift Package Manager, the design packages, the JS interop cut-off, direct native interop. Nearly every one is, in practice, a plugin migration. Production Flutter apps rarely break because of the framework; they break because a transitive dependency stopped being maintained and a platform requirement finally exposed it. Dependency health needs to be a recurring engineering task: who maintains each plugin, whether it supports SPM, built-in Kotlin and material_ui, and what the plan is if it doesn't. Forking a small, abandoned plugin is often cheaper than waiting for it.
Native integrations. Direct interop shifts the skills a Flutter team needs. Teams wrapping native SDKs should have at least one engineer per platform who is comfortable with that platform's threading and memory model, because generated bindings expose them in a way platform channels did not.
Testing and release management. The Android Intent change and the restriction on runtime engine flags both behave differently in release than in debug and profile. That's the right security trade-off, but it breaks a common assumption: that QA on a debug build is representative of production. Deep links, notification taps, launcher shortcuts and add-to-app entry points need smoke tests against release builds in CI.
Long-term maintainability. Deprecations in 3.50 come with long runways, and the temptation is to treat runway as permission to wait. In our view, the most maintainable posture is to take migrations early, while they're optional and the old path still works as a fallback.
For the business
Technology investment and maintenance cost. Framework upgrades are a recurring cost of owning a product, not a one-off. Flutter 3.50 makes that cost more predictable, through published release windows and early deprecations, but also less optional: CocoaPods' read-only date, the AGP 10 requirement for plugins and the Xcode 27 SDK rules are set by others. Maintenance spend increasingly concentrates in the dependency layer, which is worth knowing when budgeting.
Upgrade planning. The practical model is to budget for platform work every quarter, in step with Flutter's release windows, rather than letting it accumulate into an annual crisis. Small, regular upgrades are cheaper to test, easier to roll back and less likely to collide with a feature launch.
Reducing technical debt. Deprecation warnings are technical debt with a due date printed on them. Treating them as backlog items with owners turns an unpredictable future cost into a predictable present one.
Avoiding unnecessary redevelopment. Products get rewritten when the gap between the codebase and its platform grows too wide to close incrementally. Every release that is absorbed on time narrows that gap. In that sense, staying current is the cheapest insurance against a rebuild.
What this means for teams building digital products
Pull the threads of 3.50 together and a few principles emerge. None is new, but this release makes each of them more expensive to ignore.
Treat the framework as a supply chain, not a single dependency. A Flutter product now rests on the SDK, a versioned design library, a set of plugins at different stages of migration, and platform toolchains with their own deadlines. Each moves on its own schedule. Someone needs to own that picture, the way someone owns the product roadmap.
Put boundaries where the platform is moving. Native integrations and the design layer are where Flutter is changing fastest. Isolating them behind your own interfaces and components is what turns a framework migration from a project into a task.
Test the build you ship. As platforms tighten security, debug and release builds diverge in ways that matter. Release-mode testing belongs in CI, not in the final week before launch.
Plan platform work as product work. Upgrades compete with features for the same engineers. Treating them as invisible maintenance means they lose that competition until a deadline forces the issue. Scheduled, visible and estimated, they're far cheaper.
Choose the right tool for each surface. Flutter 3.50 strengthens the case for Flutter on mobile, desktop and app-like web experiences. It doesn't change the case for content-led web, where document-first frameworks remain the better fit. A product can, and often should, use both.
Upgrading: guidance by project type
Before anything else, one security step applies to every team. Following the compromise of several eMudhra intermediate certificate authorities in October 2026, Google advises that Flutter and Dart apps targeting Android, Windows or Linux be built with Flutter 3.47.8 or later (with Dart 3.13.7 or later) and then rebuilt and redistributed. (Google advisory) If you're still on an earlier 3.47 release, don't let planning for 3.50 delay that patch.
New Flutter projects. Start on 3.50. You get material_ui imports, current Android toolchain defaults and SPM from day one, with no migration debt. Design your native integration and design-system boundaries from the start.
Existing applications. Upgrade, but sequence it: SDK first on a branch, then the design-package migration as its own change with golden-test comparison, then the Android and Apple toolchain updates. Keeping these as separate commits makes regressions traceable.
Applications with complex native integrations. Wait for your key plugins to confirm 3.50 compatibility, and test Android entry points in release mode before anything else. If you maintain in-house plugins, plan the move to built-in Kotlin and SPM now, and evaluate Pigeon's native interop mode on one plugin rather than all of them.
Large applications with many third-party dependencies. Start with an inventory, not an upgrade. Run flutter pub outdated, then check each plugin for SPM, built-in Kotlin and material_ui support. Decide in advance what you'll do about each holdout: wait, replace or fork.
Flutter web projects. Add --no-deprecated-js-interop to a CI job now, even if it's allowed to fail for a while; it's your map of what blocks Wasm. Move to --web-content-hash with matching cache headers, check SafeArea behaviour on mobile browsers, and measure Wasm on Safari and Firefox against your own workloads before opting in.
Teams maintaining apps across Apple and Android. Confirm that every macOS build machine is Apple Silicon, including those that produce Android builds. Make sure the UIScene migration has completed for the iOS 27 SDK, move fully to SPM before the CocoaPods deadline, and plan to test Hybrid Composition++ if you use Android platform views.
Before you ship an app built on 3.50
- Security patch. Confirm you're on Flutter 3.47.8 or later for Android, Windows and Linux builds.
- Release-mode Android entry points. Build a release APK or app bundle and exercise every deep link, notification tap, launcher shortcut and add-to-app entry point. Search for the five Intent extra keys listed in the migration guide.
- Dependency readiness. Every plugin checked for SPM, built-in Kotlin and
material_uisupport, with a decision recorded for each holdout. - Design migration.
dart fixmigration run, localization delegates migrated by hand, golden tests compared, third-party widgets checked visually. - Text rendering. Soft hyphens in localised strings, inline widgets in RTL text and, on the web,
SafeAreawithviewport-fit=cover. - Build infrastructure. Apple Silicon macOS runners, current Xcode, and a web CI job with
--no-deprecated-js-interop.
If you're coming from a release older than 3.47, you also inherit that release's changes, most notably Impeller as the default desktop renderer. (Impeller docs) Desktop apps should get a visual pass on text rendering and custom shaders.
Looking ahead
Flutter has been unusually explicit about what comes next. According to the 3.50 announcement, future releases are expected to make Wasm the default on Safari and Firefox, make Hybrid Composition++ the stable default on Android, remove the Swift Package Manager opt-out and CocoaPods fallback, drop Intel Mac host support and keep reducing iOS input latency. The legacy JS interop libraries are slated for removal in a future Dart release. (Flutter blog)
None of these is a new direction. Each is the second half of a move already under way. A sensible 2027 plan treats each one as a known future breaking change and schedules the preparation while the old paths still work.
Two process changes deserve as much attention as the technical ones: the public release windows that made this year's releases arrive on schedule, and a new public Request for Comments process in a flutter/rfc repository for technical design decisions. For organisations whose product roadmaps depend on Flutter, being able to see, and comment on, a design change while it's still a proposal is worth more than any individual widget.
Closing thoughts
It would be easy to file Flutter 3.50 under housekeeping: deprecations, toolchain bumps, a security fix, some moved imports. We read it differently. Flutter is unwinding a decade of convenient defaults: the design system bundled into the SDK, every native call routed through one asynchronous bus, every host machine and dependency manager supported indefinitely. Those defaults made Flutter easy to adopt. Unwinding them is what will make it easier to live with.
The same is true of the products built on it. The apps that absorb this release smoothly won't be the ones with the cleverest code. They'll be the ones whose teams kept their dependencies honest, drew boundaries where the platform was likely to move, tested what they actually ship, and treated upgrades as part of building the product rather than a tax on it. Those habits are invisible in a demo and decisive over the life of a product. That's the real choice behind any technology decision, and Flutter 3.50 is a useful reminder to make it deliberately.
References & further reading
Official sources
- Flutter team, What's new in Flutter 3.50
- Flutter 3.50.0 release notes
- Breaking changes and migration guides
- Migrate to the standalone material_ui and cupertino_ui packages
- Stricter Android Intent verification for Flutter entrypoints
- Restrict Android engine flags in release mode
- Web viewport-fit=cover SafeArea support
- Flutter team, What's new in Flutter 3.47
- Flutter team, What's new in Flutter 3.41
- Native interop overview
- Pigeon and native interop
- UIScene adoption guide
- Impeller rendering engine
- Upgrading Flutter
- Google, Updates required to remediate eMudhra certificate compromise
- flutter-announce mailing list
Industry perspective
Performance figures cited in this article (iOS touch latency, Wasm frame rates and CanvasKit download size) are as reported by the Flutter team and have not been independently reproduced.
