When Flutter 3.47 shipped on August 12, 2026, it put six separate migrations in front of your project at once: the iOS/macOS minimum version bump, the UIScene requirement, the material_ui/cupertino_ui package split, the SwiftPM transition, Impeller becoming the default on desktop, and Wasm readiness. This Flutter 3.47 migration checklist scores each of them 0-2 and surfaces your project's real risk level in 15 minutes.
💡 Pro Tip: Fill out the checklist in a second pass, not in one sitting — rundart fix --apply --code=migrate_design_widgetson a separate branch and review the diff first, so your scores reflect the real state ofpubspec.yamlandAppDelegate, not assumptions.
Table of Contents
- How to Score
- The 12-Item Risk Check
- 1. Minimum iOS/macOS Version
- 2. UIScene Adoption Status
- 3. Number of material/cupertino Imports
- 4. flutter_localizations Usage
- 5. dart:html Usage (Wasm Readiness)
- 6. Plugin SwiftPM Status
- 7. CocoaPods Dependencies
- 8. Impeller Compatibility and Custom Shaders
- 9. Platform View Usage
- 10. CI Xcode Version (Xcode 27 Readiness)
- 11. Intel Mac Build Machines
- 12. Dart 3.13 Compatibility
- Bonus: Android/Kotlin Alignment
- A Common Misconception: the "ChangeNotifier Moved" Claim
- Risk Score Bands
- Migration Plan by Band
- The 5 Most Common Breakages and Their Fixes
- FAQ
- Is my Flutter project ready for 3.47?
- How many days does the Flutter 3.47 migration take?
- Which packages break in 3.47?
- What should I do before the November deprecation?
- Do I need to drop CocoaPods entirely?
- Should I switch to material_ui and cupertino_ui right away?
- Conclusion
- Sources
How to Score
The 12 items below form a 24-point scale in total. Score each item 0, 1, or 2 based on your project's state:
- Score 0: The item doesn't affect your project at all, or you're already fully compliant.
- Score 1: There's partial risk; it needs review but isn't urgent.
- Score 2: Direct risk; it requires a code change or a dependency update.
While scoring, keep the official Flutter 3.47 announcement open side by side with your project's pubspec.yaml and ios/Runner/AppDelegate.swift. Each item below links to a separate, deep-dive post on the topic; here you'll only find what to check for scoring purposes.
I'd recommend filling out the scoring with your team rather than alone: the person who last touched AppDelegate.swift, the person who added the dependencies in the Podfile, and the person who owns the CI pipeline are usually different people. Working through each item by asking "who knows this" gives a far more reliable result than one person guessing at scores.
The 12-Item Risk Check
1. Minimum iOS/macOS Version
With Flutter 3.47, the supported minimum versions went up:
Platform | 3.46 and earlier minimum | 3.47 minimum |
|---|---|---|
iOS | 13 | 15 |
macOS | 10.15 | 12 |
Score 2 if your deployment target is below these thresholds, 0 if it's already at or above them; an in-between state (not yet tested in CI, say) warrants 1. Don't check Info.plist — the iOS deployment target lives in two places: the Deployment section of the Runner target's Build Settings in Xcode, and the platform :ios line in the Podfile. Check both; they can drift apart. The reason for the higher thresholds, per the announcement, is Xcode 27 support — so if you're planning that move, this item is a prerequisite, not an optional improvement.
2. UIScene Adoption Status
Flutter has supported the UIScene lifecycle by default since 3.41, but the real risk is this: the iOS 27 SDK makes UIScene mandatory for all UIKit-based apps, and apps built with Xcode 27 that haven't adopted it fail to launch. The Flutter CLI handles this migration automatically for most apps; but custom native code in AppDelegate, or a plugin still relying on the legacy lifecycle, means manual migration — score 2 then, 0 on the fully default template. Apple shipped Xcode 27, iOS 27, and macOS 27 on September 14, 2026, so this item is now a live risk, not preparation: don't score it 0 without building with the shipped Xcode 27 and running a launch test on a real device. For the detailed steps, see our UIScene requirement post.
3. Number of material/cupertino Imports
If your package:flutter/material.dart or cupertino.dart imports still come from the core SDK, that's fine for today, but these classes will be officially deprecated in the fall stable release in November 2026. Score 2 if you have this import across dozens of files in your project and haven't moved to the material_ui/cupertino_ui packages yet; 1 if you have a migration plan; 0 if you've already moved. For the full package split, see our material_ui and cupertino_ui migration guide — this post only gives you the scoring criterion, not the detail.
4. flutter_localizations Usage
The flutter_localizations package was also unbundled; the localization delegates now live inside package:material_ui and package:cupertino_ui. What determines the risk isn't the class name but the source of the import: score 2 if you're still importing GlobalMaterialLocalizations from package:flutter_localizations, 1 if you're bridging it through MaterialUiCompatibilityBridge, 0 if you're using GlobalMaterialLocalizations.delegates from package:material_ui.
5. dart:html Usage (Wasm Readiness)
Since Wasm compilation is still opt-in (the --wasm flag), this item isn't urgent, but if your project has code using dart:html, it won't work once you move to Wasm — the legacy library isn't supported, and you need the package:web JS interop package instead. Score 2 if you have a dart:html import and a Wasm target; 1 if you have dart:html but no Wasm plan; 0 if you don't use it at all.
1# To scan for legacy imports not yet migrated in your project2grep -rn "import 'dart:html'" lib/3grep -rln "package:flutter/material.dart" lib/ | wc -l6. Plugin SwiftPM Status
The community has made major progress on the SwiftPM transition: 92 of the top 100 iOS plugins now support Swift Package Manager. Score 2 if most of the plugins you use fall outside that 92 (still CocoaPods-only); 1 if you're in a mixed state; 0 if all of them support SwiftPM.
Don't guess this one; the most direct source is the build output itself. If your app depends on plugins that haven't migrated to SwiftPM, Flutter prints a warning listing exactly which dependencies aren't supported and falls back to CocoaPods for them — so one iOS build run gives you the score directly. To verify plugin by plugin, check the plugin's own repo: SwiftPM support means a Package.swift file plus source files moved into the standard Swift package layout; no Package.swift means no migration yet. If you'd disabled SwiftPM before, turn it back on with flutter config --enable-swift-package-manager and try again — the warning list only means something once you do.
7. CocoaPods Dependencies
CocoaPods is now in maintenance mode, and its registry will become permanently read-only on December 2, 2026: existing builds keep working, but no new versions or new pods get added to trunk after that date. Plugins that don't migrate to SwiftPM will eventually stop working, and their pub.dev scores are already declining. Score 2 if your Podfile still has multiple active dependencies, 1 if only 1-2 small dependencies remain, 0 if you've dropped CocoaPods entirely. Periodically reviewing pod list output and noting whether each dependency has a SwiftPM alternative gives you a clear priority order before the December registry change.
8. Impeller Compatibility and Custom Shaders
In Flutter 3.47, Impeller became the default rendering engine on macOS, Windows, and Linux. The option to fall back to Skia still exists but will be removed in a future release. Score 2 if your project has custom shaders (FragmentShader) or Skia-specific low-level drawing code; 1 if you have a desktop target but don't use shaders; 0 if you have no desktop target. For the internals of the rendering engine and its performance impact, see our Impeller rendering engine post.
9. Platform View Usage
If you're embedding native iOS views via platform views (maps, video players, native SDK UI components, and the like), 3.47 improved gesture propagation for these views — behavior may change. Score 1 if your app has active platform view usage (it needs testing, not breaking, but there's a risk of behavior differences); 2 if you have heavy/complex gesture scenarios; 0 if you don't use platform views.
10. CI Xcode Version (Xcode 27 Readiness)
Xcode 27 is no longer a beta: it shipped stable on September 14, 2026, with App Store submissions open since September 9, 2026. So this item's criterion is tied directly to the shipped version: score 2 if CI is still pinned to Xcode 26 or earlier; 1 if at least one job runs Xcode 27; 0 if 27 is your default. Even the Flutter team's own brief, later-reverted experiment testing on Xcode 26/iOS 26 during 3.47 development shows why running one job regularly on the latest Xcode beats pinning CI to a single strict version.
11. Intel Mac Build Machines
In parallel with Apple's Apple Silicon transition, Flutter is gradually sunsetting support for Intel-based Macs: automated test runs on Intel hardware have been turned off, and the Flutter CLI now prints a warning when building on Intel hosts or targeting dual architecture. The announcement states explicitly that these warnings will turn into errors in a future release — so what's noise today is breakage tomorrow.
Score 2 if at least one dev or CI machine is still an Intel Mac; 1 if all are Apple Silicon but your macOS builds still produce dual architecture; 0 if you've moved to ARM64-only. To start producing an ARM64-only macOS app right away, run flutter config --enable-macos-arm64-only. Don't skip this as "just a warning" — hardware refreshes take far longer to plan than a code change, and the day warnings turn into errors, CI goes red with no code fix available.
Ask two questions separately when scoring: which architecture is the build machine, and which architectures does the output contain. Even an Apple Silicon machine keeps getting the CLI warning if it still targets dual architecture. And with automated Intel test runs off, that side is no longer tested regularly, so a problem there may go unnoticed for a while.
12. Dart 3.13 Compatibility
Dart 3.13 shipped alongside Flutter 3.47, with expanded documentation for primary constructors. This isn't a breaking change, but you need to verify your analyzer/lint rules still pass with the current Dart SDK. Score 1 if your dart analyze CI step isn't pinned to Dart 3.13, 2 if you have no CI analysis step at all, 0 if it's current. For the new language feature itself, see our Dart 3.13 primary constructors guide.
Bonus: Android/Kotlin Alignment
These 12 items cover iOS/macOS risks, but don't overlook Android if you target it: from Android Gradle Plugin (AGP) 9 onward, built-in Kotlin becomes the default, and apps/plugins using kotlin-android (the Kotlin Gradle Plugin) won't build without migrating. Flutter 3.44 gave temporary backward compatibility via android.builtInKotlin=false; 3.47 lets you enable built-in Kotlin with android.builtInKotlin=true once your app and all plugins have migrated. AGP 9 also only recognizes the new DSL interfaces, not the old types — but the Flutter team has, for now, kept the AGP DSL compatible with the old types (Issue #184838), so you can safely upgrade to AGP 9 and later; that bridge is temporary and goes away once the new DSL migration finishes (Issue #184839). I left this out of the 12-point scoring since this checklist is iOS-centric, but Android teams should track it as a separate line item.
A Common Misconception: the "ChangeNotifier Moved" Claim
Worth clearing up while scoring: some community posts claim ChangeNotifier "moved" from the core SDK to a new package:listen package. Not accurate — ChangeNotifier still lives in the core SDK and isn't deprecated; listen is a parallel, independent implementation, not a new home for it. Clear this up before scoring any ChangeNotifier code — don't tack on 2 points unnecessarily.
Risk Score Bands
Match the total score across the 12 items to the band below:
Total Score | Band | Meaning |
|---|---|---|
0-6 | Green | Your project is largely ready; the remaining items are review-level |
7-14 | Yellow | A planned migration sprint is needed; not urgent, but should start before November |
15-24 | Red | A comprehensive, staged migration plan is required; don't do it in a single commit |
When computing your band, don't let a single high-scoring item push you into the wrong band: for example, a project that scores 2 only on the UIScene item but 0-1 on the other 11 items might land in the yellow band overall, but its real priority is clearly concentrated on one item. In that case, focusing your prep work on that single item is more efficient than a general "tackle everything at once" plan.
Migration Plan by Band
The guidance in this section is based on DartWay's real migration attempt from 3.44.0 to 3.47.2; I'm not giving a day-based time estimate because the duration depends on how many items you scored a 2 on.
Green band: In DartWay's migration attempt from 3.44.0 to 3.47.2, the framework side stayed at "one command, two traps." The command is dart fix --apply --code=migrate_design_widgets. First trap: a plain dart fix --apply, run without --code=migrate_design_widgets, does nothing — the fix isn't in the default set, so the command reports success while changing nothing, and reads from the outside as "already migrated." Second trap: the command writes material_ui: any into pubspec.yaml; any means the package's next breaking release slips into your build without a word.
Go in with eyes open: run the command on a separate branch, read the diff, and replace any with a caret-pinned version. Both traps are silent — one reports success while doing nothing, the other leaves a dependency that works today but breaks without warning later. So even in the green band, do this on a branch you can diff, not directly on main.
Yellow band: The framework side moves fast, but if you have custom code in AppDelegate or multiple plugins still on CocoaPods, each of these items requires its own review and test cycle — plan for work spread over a few days total, kept in separate commits.
Red band: If UIScene, SwiftPM, and the material_ui/cupertino_ui migration are all heavy at once, advancing them in commits separate from the framework upgrade reduces risk: first bump the framework version and get tests green, then do the UI-package migration, then the plugin/SwiftPM cleanup, each on its own.
1# Automatic import migration — run it on a separate branch2git checkout -b chore/flutter-3-47-migrate-widgets3# First trap: run it without --code and the command reports success but changes no imports4dart fix --apply --code=migrate_design_widgets1# pubspec.yaml — second trap: dart fix writes "any", always pin the version2dependencies:3 material_ui: ^1.0.0 # leaving "any" lets the next breaking release slip into your build silently4 cupertino_ui: ^1.0.0The 5 Most Common Breakages and Their Fixes
- Launch failure from missing UIScene adoption: custom code in
AppDelegaterelying on the legacy lifecycle means the app fails to launch when built with the latest SDK. Fix: follow the UIScene migration guide, move that code to the UIScene delegate, and run a launch test on a real device. - Unpinned version in the material_ui migration:
dart fixwritesanyintopubspec.yaml; left unpinned, a future breaking release slips in silently and can misleadingly look like "already migrated." Fix: pin it to^1.0.0as above, and always review the diff after runningdart fix. - Leftover dart:html breaks Wasm compilation: a
dart:htmlimport causes a build error once you target Wasm, which may go unnoticed until then. Fix: switch to thepackage:webJS interop package and add an occasional Wasm build check to CI. - Plugins stuck in CocoaPods maintenance mode: plugins that haven't migrated to SwiftPM will eventually stop working, and their pub.dev scores are already declining. Fix: run your iOS build once, read Flutter's "unsupported dependencies" warning list, and for each plugin find a maintained alternative or open a Swift package support issue on its repo.
- Custom shader/Skia code behaves differently under Impeller: since Impeller is the default on desktop, Skia-specific drawing code can produce unexpected results; the Skia fallback still exists but is officially slated for removal in a future release. Fix: test shader code with Impeller early and file a bug against Flutter if you find issues.
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
I've put together a practical pre-check list, separate from the scoring table, that you can run through quickly before taking the checklist into a meeting. Check off the items below to gauge your team's readiness before starting the 12-item scoring.
FAQ
Is my Flutter project ready for 3.47?
It can't be guaranteed with a single command; you need to audit five separate areas individually: the source of your material/cupertino imports, your iOS/macOS minimum targets, whether AppDelegate has custom lifecycle code, your plugins' SwiftPM support, and your CI's Xcode version. The 12-item scoring in this post lets you review all these areas in one pass.
How many days does the Flutter 3.47 migration take?
There's no fixed number to give; the duration depends on your project's size and how many items you scored a 2 on. In DartWay's migration attempt from 3.44.0 to 3.47.2, the framework prep part stayed at "one command, two traps"; but if you have custom code in AppDelegate or a large number of plugins that haven't migrated to SwiftPM, each of these items brings its own review and test cycle.
Which packages break in 3.47?
What 3.47 brings isn't a named list of "broken packages," but a risk class: plugins that haven't migrated to SwiftPM yet. 92 of the top 100 iOS plugins have already migrated to SwiftPM; the rest, stuck in CocoaPods maintenance mode, will eventually stop working.
What should I do before the November deprecation?
I recommend two steps: run dart fix --apply --code=migrate_design_widgets on a separate branch and review the diff, then convert the any value the command writes into pubspec.yaml to a pinned version (like ^1.0.0) — if left unpinned, the next breaking release can slip into your build silently.
Do I need to drop CocoaPods entirely?
Not immediately; CocoaPods is in maintenance mode and its registry will become read-only on December 2, 2026, but your existing builds keep working. That said, plugins that don't migrate to SwiftPM will eventually stop working, and their pub.dev scores are already declining, so it makes sense to fold the transition into your plan ahead of the November deprecation.
Should I switch to material_ui and cupertino_ui right away?
Not mandatory, since the old classes in the core SDK won't be declared deprecated until November 2026. But since the dart fix --apply --code=migrate_design_widgets command provides a backward-compatible migration, and moving early lets you avoid November's abrupt change, you can treat the window up to November's deprecation as a "calmly migrate" one rather than a "panic" one.
Conclusion
Flutter 3.47 puts multiple migrations in front of you at once — from the iOS/macOS minimum version bump to the UIScene requirement, from the material_ui/cupertino_ui package split to the SwiftPM transition. The 12-item scoring in this post lets you separate, with a clear score, which areas are urgent and which can stay at review-level. For the details of the package split, see the material_ui and cupertino_ui migration guide; for the step-by-step UIScene migration, the UIScene requirement post; for the performance impact of the rendering engine change, the Impeller rendering engine post; and to understand the language-side addition, the Dart 3.13 primary constructors guide. If you want to keep visual regressions under control throughout the migration, the Flutter testing guide will help, and for a general performance baseline, the Flutter performance optimization guide is useful too.
Sources
- What's new in Flutter 3.47 — primary source for the iOS/macOS minimum versions, the UIScene requirement, material_ui/cupertino_ui 1.0, SwiftPM progress, the sunsetting of Intel Mac support, and Impeller becoming the default rendering engine.
- UIScene adoption — breaking changes — the official technical details of the UIScene migration.
- Swift Package Manager for plugin authors — the SwiftPM template and
Package.swiftrequirement for plugin authors. - Flutter 3.47.0 release notes — the release notes and CI/test infrastructure changes.
- Saying goodbye to CocoaPods — CocoaPods's maintenance mode, the registry becoming read-only on December 2, 2026, and the Flutter CLI's warning listing unsupported dependencies.
- pub.dev — material_ui — MaterialUiCompatibilityBridge and the current package version.
- Dart — What's new — Dart 3.13 release notes and the expanded primary constructors documentation.
- DartWay — Flutter 3.47: what actually breaks — a real project's migration attempt from 3.44.0 to 3.47.2; the two traps of the
dart fixcommand and the debunking of theChangeNotifier/package:listenmisconception. - Migrating Flutter Android projects to built-in Kotlin — the official technical details of the AGP 9 and built-in Kotlin migration.
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy

