Safeguard
Developer Tools•

Gradle version catalogs: one file, but versions are only requests

A Gradle version catalog centralizes dependency coordinates in libs.versions.toml for every subproject, but the versions are requests, not guarantees.

Safeguard Security Team
3 min read

A Gradle version catalog is a file, usually gradle/libs.versions.toml, that lists dependency coordinates and versions once for every project in a build. Subprojects use type safe aliases instead of repeating strings. One caution from the docs: catalog versions are requests, so conflict resolution can still select a different version.

The four sections

The Gradle documentation describes the file layout:

[versions]
groovy = "3.0.5"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

[plugins]
versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }

Versions holds named version identifiers. Libraries map aliases to coordinates, optionally pointing at a version with version.ref. Bundles group library aliases. Plugins map plugin IDs to versions.

Using aliases

In a subproject's build script you write the alias, with dashes turned into dots:

  • implementation(libs.groovy.core) for a library
  • implementation(libs.bundles.groovy) for a bundle
  • alias(libs.plugins.versions) in the plugins block

The catalog is visible to all projects in the build, so every module sees the same aliases. A typo is a compile error in the build script, not a silent new dependency.

Why it helps a multi module build

You change a version in one place. Reviewers see one line. Security teams can grep one file to answer "which version of this library do we request." That is a real gain over dozens of build files with their own strings.

The caveat

The docs state that versions in a catalog are requests, not enforced versions. Conflict resolution, platforms or constraints can still pick another version. If another dependency asks for a higher version, Gradle may select it.

So the catalog tells you what you asked for, not always what you ship. To see what you ship, inspect the resolved graph with ./gradlew dependencies, or look at an SBOM from the build.

Pair it with verification

Because the catalog does not lock anything on its own, combine it with dependency locking or verification so the resolved result is fixed and reviewable. See Gradle dependency verification.

A review checklist

  1. Any new library alias in the catalog gets a reviewer who checks the coordinates, since a lookalike group or name is a classic trick.
  2. Bundles should be small and purposeful. A bundle can hide an extra dependency.
  3. Plugins are code that runs in your build. Treat plugin entries as seriously as library entries.

Safeguard dependency and SBOM scanning can list the artifacts a Gradle build resolves and flag known vulnerabilities. You can try a free scan at gold.safeguard.sh/scan.

Quick check

Does the catalog pin the version I get?

Not by itself. The docs say catalog versions are requests and resolution can select another version.

How is groovy-core written in a build script?

As libs.groovy.core, with dashes becoming dots.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.