Mastering Gradle Version Catalog: Unified Dependency Management for Multi‑Module Projects

This article explains how Gradle 7's Version Catalog feature lets you centralize and share dependency versions, bundles, and plugin declarations across modules and projects, offering type‑safe accessors, version separation, and easy publishing through Maven, with practical code examples and configuration steps.

Programmer DD
Programmer DD
Programmer DD
Mastering Gradle Version Catalog: Unified Dependency Management for Multi‑Module Projects

I estimate few developers use such a high Gradle version, so this guide serves as a handy reference for future needs.

Requirements for large projects

Unified dependency management in a single file.

Consistent dependency versions across different modules.

Consistent dependency versions across different projects.

Existing solutions include loop‑optimized Gradle dependency management, buildSrc usage, and includeBuild for shared versions, but Gradle 7 introduces a new feature: Version Catalog , which provides the following capabilities:

Visibility to all modules for unified dependency control.

Support for declaring dependency bundles that are always used together.

Separation of version numbers from dependency names, enabling shared versions.

Configuration of dependencies in a separate libs.versions.toml file.

Sharing dependencies between projects.

1. Using Version Catalog

Enable the incubating feature in settings.gradle: enableFeaturePreview('VERSION_CATALOGS') Declare dependencies in the catalog and use them via the generated libs accessor:

dependencies {<br/>    implementation(libs.retrofit)<br/>    implementation(libs.groovy.core)<br/>}

Benefits:

Gradle generates type‑safe accessors for IDE auto‑completion.

All modules see the same version declarations, allowing a single change to propagate.

Bundles can group frequently used dependencies.

Version numbers can be shared across multiple dependencies.

2. Declaring the Version Catalog

Add the catalog definition to settings.gradle(.kts):

dependencyResolutionManagement {<br/>    versionCatalogs {<br/>        libs {<br/>            alias('retrofit').to('com.squareup.retrofit2:retrofit:2.9.0')<br/>            alias('groovy-core').to('org.codehaus.groovy:groovy').versionRef('groovy')<br/>            alias('groovy-json').to('org.codehaus.groovy:groovy-json').versionRef('groovy')<br/>            alias('groovy-nio').to('org.codehaus.groovy:groovy-nio').versionRef('groovy')<br/>            alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {<br/>                strictly '[3.8, 4.0['<br/>                prefer '3.9'<br/>            }<br/>            version('groovy', '3.0.5')<br/>            version('compilesdk', '30')<br/>            version('targetsdk', '30')<br/>        }<br/>    }<br/>}

Alias names should consist of ASCII characters, preferably lowercase, separated by dashes, underscores, or dots.

3. Dependencies with the Same Version

Define a shared version and reference it in multiple aliases:

dependencyResolutionManagement {<br/>    versionCatalogs {<br/>        libs {<br/>            version('groovy', '3.0.5')<br/>            alias('groovy-core').to('org.codehaus.groovy', 'groovy').versionRef('groovy')<br/>            alias('groovy-json').to('org.codehaus.groovy', 'groovy-json').versionRef('groovy')<br/>            alias('groovy-nio').to('org.codehaus.groovy', 'groovy-nio').versionRef('groovy')<br/>        }<br/>    }<br/>}

You can also retrieve these versions in build scripts, e.g., for compileSdk and targetSdk:

android {<br/>    compileSdk libs.versions.compilesdk.get().toInteger()<br/>    defaultConfig {<br/>        minSdk 21<br/>        targetSdk libs.versions.targetsdk.get().toInteger()<br/>    }<br/>}

4. Dependency Bundles

Group related libraries into a bundle:

dependencyResolutionManagement {<br/>    versionCatalogs {<br/>        libs {<br/>            bundle('groovy', ['groovy-core', 'groovy-json', 'groovy-nio'])<br/>        }<br/>    }<br/>}

Use the bundle in a module:

dependencies {<br/>    implementation libs.bundles.groovy<br/>}

5. Plugin Versions

Declare plugin versions in the catalog:

dependencyResolutionManagement {<br/>    versionCatalogs {<br/>        libs {<br/>            alias('jmh').toPluginId('me.champeau.jmh').version('0.6.5')<br/>        }<br/>    }<br/>}

Apply the plugin:

plugins {<br/>    id 'java-library'<br/>    id 'checkstyle'<br/>    alias(libs.plugins.jmh)<br/>}

6. Configuring Catalog via libs.versions.toml

A TOML file can declare versions, libraries, bundles, and plugins. Example:

[versions]<br/>groovy = "3.0.5"<br/>checkstyle = "8.37"<br/>compilesdk = "30"<br/>targetsdk = "30"<br/><br/>[libraries]<br/>retrofit = "com.squareup.retrofit2:retrofit:2.9.0"<br/>groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }<br/>groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }<br/>groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }<br/>commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer = "3.9" } }<br/><br/>[bundles]<br/>groovy = ["groovy-core", "groovy-json", "groovy-nio"]<br/><br/>[plugins]<br/>jmh = { id = "me.champeau.jmh", version = "0.6.5" }

7. Sharing Catalog Between Projects

Import a catalog from an external TOML file:

dependencyResolutionManagement {<br/>    versionCatalogs {<br/>        libs {<br/>            from(files("../gradle/libs.versions.toml"))<br/>        }<br/>    }<br/>}

You can also define multiple catalogs, e.g., testLibs from test-libs.versions.toml.

8. Publishing a Catalog as a Plugin

Apply the version-catalog and maven-publish plugins, define a catalog extension, and publish it:

plugins {<br/>    id 'version-catalog'<br/>    id 'maven-publish'<br/>}<br/><br/>catalog {<br/>    versionCatalog {<br/>        from files('../libs.versions.toml')<br/>    }<br/>}<br/><br/>publishing {<br/>    publications {<br/>        maven(MavenPublication) {<br/>            groupId = 'com.zj.catalog'<br/>            artifactId = 'catalog'<br/>            version = '1.0.0'<br/>            from components.versionCatalog<br/>        }<br/>    }<br/>}

Consume the published catalog via mavenLocal() or a remote Maven repository and override versions if needed.

Summary

Version Catalog is visible to all modules, enabling unified dependency management.

Supports dependency bundles for groups of libraries used together.

Separates version numbers from dependency coordinates, allowing shared version definitions.

Allows configuration via a dedicated libs.versions.toml file.

Facilitates sharing dependencies across multiple projects.

Reference: Gradle documentation on platforms and rich version constraints.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBuild Automationdependency managementGradleKotlinVersion Catalog
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.