How do you centralize plugin versions using the plugins {} sub-block inside pluginManagement, and how do build scripts then apply those plugins?
answer
- plugins {} inside pluginManagement sets versions only
- does not apply
- build script applies id with no version
- single edit updates all modules
- conflicts if version also in build script
basics
~10 sDeclare id("...") version "x" once in pluginManagement { plugins { } } in settings. Then each build script applies the plugin with just the id and no version.
solid answer
~40 sInside `pluginManagement {}` you can add a `plugins {}` sub-block that declares plugin ids together with their **versions** in one central place. This does **not** apply the plugins — it only fixes the version. Then every project's build script applies the plugin via the normal `plugins {}` DSL using only the id (`id("...")`) with no `version`. Gradle looks the version up from the settings-level declaration. This keeps versions consistent across a multi-project build and means a single edit in settings updates everyone. It is a structural/DSL convenience; the actual resolution still goes through the configured plugin repositories. Note this is distinct from a version catalog's `[plugins]` table, though both aim at version centralization.
code
kotlin · 12 lines// settings.gradle.kts
pluginManagement {
repositories { gradlePluginPortal() }
plugins {
id("org.jetbrains.kotlin.jvm") version "2.0.20"
}
}
// app/build.gradle.kts
plugins {
id("org.jetbrains.kotlin.jvm") // no version — taken from settings
}go deeper
Know that you can put plugin versions in one place and apply by id elsewhere.
Explain that it sets versions only, build scripts apply without a version, and conflicts arise if both specify a version.
Compare with version-catalog [plugins] and recommend a consistent project-wide convention.
Define org policy: single source of truth for plugin versions, drift prevention, and CI enforcement across teams.
## The problem it solves In a multi-module build, if each `build.gradle.kts` writes `id("org.jetbrains.kotlin.jvm") version "2.0.20"`, the version string is duplicated everywhere. Bumping it means editing many files and risking drift (two modules on different versions of the same plugin can cause subtle classpath problems). ## The settings-level plugins {} block `pluginManagement {}` accepts a `plugins {}` sub-block whose **only** job is to associate a plugin id with a version build-wide: ```kotlin // settings.gradle.kts pluginManagement { repositories { gradlePluginPortal() } plugins { id("org.jetbrains.kotlin.jvm") version "2.0.20" id("com.github.ben-manes.versions") version "0.51.0" } } ``` This declaration **does not apply** anything — no project gets the Kotlin plugin from this alone. It simply registers the version. ## Applying from build scripts Each build script then applies by id, **omitting** the version: ```kotlin // app/build.gradle.kts plugins { id("org.jetbrains.kotlin.jvm") // version comes from settings } ``` Gradle resolves the version from the settings declaration. If a build script *does* specify a version while one is also set in settings, that is an error (conflicting versions for the same plugin). ## Relationship to version catalogs Gradle also offers **version catalogs** (`gradle/libs.versions.toml` with a `[plugins]` table) which can centralize plugin versions and are applied like `alias(libs.plugins.kotlinJvm)`. The `pluginManagement { plugins { } }` approach predates and complements catalogs; many modern builds prefer the catalog for plugins but the settings `plugins {}` block remains valid and is common for convention/shared-build setups. ## Key distinctions - `pluginManagement { plugins { } }` — sets versions, does not apply. - `plugins { }` in a build script — applies (and, when version omitted, borrows the settings version). - Both are the `plugins {}` DSL but in different scripts with different meaning.
- Does declaring a plugin in pluginManagement { plugins { } } apply it to any project?No. It only fixes the version centrally. A project must still apply it via the plugins {} DSL in its own build script.
- What happens if a build script specifies a version for a plugin that already has one in settings?Gradle reports a conflict — the same plugin id is given two versions. Remove the version from the build script and let it inherit from settings.
saying these in an interview costs you the question
- Claiming the settings plugins {} block applies the plugin everywhere
- Specifying versions in both settings and build scripts
- Confusing the settings plugins {} block with the build-script plugins {} block