Search code examples
javakotlingradle

Why is using a Version Catalog considered best practice over `pluginManagement.plugins {}` in `settings.gradle`?


I’ve been exploring Gradle’s plugin management and came across the following distinctions:

  • The pluginManagement { plugins { } } block in settings.gradle is used solely to configure plugin versions and resolution strategies. It doesn’t actually apply plugins—it merely centralizes the version information for plugins that will be applied later via the top-level plugins { } block in either settings.gradle or build scripts.

  • In contrast, the top-level plugins { } block both resolves and applies plugins to the project.

I found documentation and discussions (a Stack Overflow reference) that recommend using a Version Catalog to centrally define plugin versions instead of relying on the pluginManagement { plugins { } } block.

Official Kotlin documentation also recommands using Version Catalog.

My question is:

What are the concrete benefits of using a Version Catalog for plugin version management compared to using the pluginManagement { plugins { } } block in settings.gradle? Is it purely for centralization and dynamic version retrieval, or are there additional reasons (such as build performance, maintainability, or clarity) that make it the best practice?

Additionally, are there any official references or deeper technical explanations in the Gradle source or documentation that clarify this preference?


Solution

  • Version catalogs

    A version catalog is a centralised way of setting versions, library coordinates and plugin ids in a centralised, type-safe way since placing them there generates accessors for the values in all projects.

    You could create similar features by writing code to do so in buildSrc or your own plugin that was applied in relevant builds. However the version catalog does so using a standard API, which naturally offers advantages over every project implementing their own style of version catalog (and I remember my efforts to do so!).

    Using constraints in the settings file

    There are several issues with fixing plugin (and possibly library) versions in the settings file:

    • This would require ids and artifact coordinates to be written as error-prone strings in the settings file and all build files where it was applied
    • What if one of your projects needed to use a different version of a plugin to all the others? That might not be too easy to arrange
    • This approach is also not as "declarative" as using the version catalog accessors in build file: it is preferable for each build file to set out specification of its build, not have aspects set mysteriously from other files. It's not as easy to quickly see why versions are set the way they are.

    It simply doesn't achieve all the benefits of the version catalog.