Skip to main content

.flutter-plugins-dependencies replaces .flutter-plugins.

Summary

#

The flutter tool will no longer output the .flutter-plugins metadata file, and only output .flutter-plugins-dependencies.

Tools and build scripts, such as Gradle configurations (for Android apps) that rely on the presence of .flutter-plugins need to be updated.

Background

#

In 2019, .flutter-plugins-dependencies was added as a newer file format that replaces .flutter-plugins.

So a file that looked something like this:

.flutter-plugins
camera=/path/to/camera/plugin
shared_preferences=shared_preferences

Was replaced by something like this:

.flutter-plugins-dependencies
json
{
  "dependencyGraph": {
    "camera": {
      "name": "camera",
      "version": "0.10.0",
      "dependencies": {
        "flutter": "0.0.0"
      }
    },
    "shared_preferences": {
      "name": "shared_preferences",
      "version": "2.0.15",
      "dependencies": {
        "flutter": "0.0.0"
      }
    }
  },
  "flutter": {
    "frameworkRevision": "3a0f99d4f2",
    "channel": "stable"
  }
}

Generating both files is a source of technical debt that complicates new feature sets, such as not bundling dev_dependency plugins in a release app.

Migration guide

#

Most Flutter developers don't parse or use this file, but build configurations might, including the settings.gradle file as generated by older invocations of flutter create --platforms android. These legacy files might still reference .flutter-plugins and must be updated to a newer build script.

For example:

settings.gradle
groovy
include ':app'

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()

def plugins = new Properties()
// Note explicitly reading the legacy '.flutter-plugins' file.
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}

plugins.each { name, path ->
    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
    include ":$name"
    project(":$name").projectDir = pluginDirectory
}

Might be upgraded to its settings.gradle.kts equivalent:

settings.gradle.kts
kts
pluginManagement {
    val flutterSdkPath = run {
        val properties = java.util.Properties()
        file("local.properties").inputStream().use { properties.load(it) }
        val flutterSdkPath = properties.getProperty("flutter.sdk")
        require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
        flutterSdkPath
    }

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    // Note the use of the flutter-plugin-loader versus reading '.flutter-plugins'
    id("dev.flutter.flutter-plugin-loader") version "1.0.0"
    id("com.android.application") version "8.1.0" apply false
    id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}

include(":app")

For help switching to the newer plugin DSL, check out Deprecated imperative apply of Flutter's Gradle plugins.

To smoke test whether your build relies on a .flutter-plugins file, you can use the feature flag explicit-package-dependencies:

flutter config explicit-package-dependencies

Any build tools or scripts that might rely on the .flutter-plugins file being output will now fail.

Timeline

#

Landed in version: Not yet
Stable release: Not yet

One stable release after this change lands, .flutter-plugins will no longer be generated.

References

#

Relevant Issues:

  • Issue 48918, where .flutter-plugins was (in 2020) slated for deprecation.

Relevant PRs:

  • PR 45379, where .flutter-plugins-dependencies was originally added.
  • PR 157388, where a warning was added to the Flutter Android build scripts.