In this article

A Flutter Plugin DSL migration changes how Gradle plugins are applied. It is not automatically an Android Gradle Plugin or Kotlin version upgrade. Preserve the project's working versions while moving the relevant configuration, then validate every release variant.

Flutter's migration guide, checked October 8, 2026, dates Plugin DSL support to Flutter 3.16 and warns that breaking-change guidance is release-specific. Read the guide against your installed Flutter version rather than treating its example versions as current recommendations.

First classify the error#

Determine whether the failure names the legacy imperative Flutter plugin application, a plugin-resolution error, an AGP incompatibility or a duplicate Kotlin plugin. These may occur in the same project but are not the same migration.

Capture the current Flutter, Gradle, AGP, Kotlin and Java versions plus the first failing message. Inspect settings.gradle or its Kotlin equivalent, the root build file and the application build file. Keep a small before-and-after diff.

Map responsibilities before moving declarations#

Settings configuration resolves the Flutter SDK and establishes plugin management. Module configuration applies plugins to the app. Flutter's guide distinguishes the settings loader dev.flutter.flutter-plugin-loader from the app plugin dev.flutter.flutter-gradle-plugin.

Confusing those identifiers can produce a new error after the old apply from line is removed. Do not copy a module block into settings merely because both contain a plugins block.

For each existing plugin, record where its version is declared, where it is applied and whether custom initialization depends on the old layout. Include Google Services, Crashlytics and project-specific plugins.

Migrate syntax without discarding custom work#

Follow the current guide's ordering requirements for pluginManagement and plugins. Retain the Flutter SDK resolution appropriate to the project. Move the relevant plugin declarations and remove obsolete imperative application only after its replacement is present.

Do not replace every build file with a generated sample. Existing flavors, signing configuration, repositories, native modules and release tasks can disappear in such a rewrite.

Likewise, do not keep both the old and new application paths to “be safe.” Duplicate application can obscure the actual source of configuration or fail outright.

Validate a matrix rather than one debug run#

Choose the variants your team actually distributes. For each, verify:

  • Gradle configuration completes without plugin-resolution errors.
  • The intended app builds in the required mode.
  • The resulting package identity and version remain correct.
  • Relevant plugin-generated outputs still exist.
  • The app starts and its important native features work.

If CI and a developer's machine disagree, compare the recorded toolchain and resolved dependency versions before deleting caches. A local cached build is weak evidence that a clean runner can resolve the migrated setup.

Keep AGP 9 work separate#

Built-in Kotlin and new AGP DSL compatibility introduce additional considerations in newer Flutter and plugin versions. Do not infer that completing this older Plugin DSL migration establishes AGP 9 readiness.

Use a separate compatibility check for that upgrade and preserve the syntax-migration diff so regressions can be attributed. Combining several migrations may be unavoidable, but document each acceptance condition independently.

Review the diff before shipping#

Look for accidental removal of flavor settings, signing references, custom tasks or dependency plugins. A migration is complete when the intended build variants retain their behavior and the deprecated path is gone.

Our AI-generated code review checklist is useful when a tool supplies a complete replacement file: ask why each removed section is safe to remove, rather than accepting a shorter file as proof of correctness.