Antlers

Fast, native JVM dependency resolution without the JVM.

Antlers is a native JVM dependency resolver written in Rust. It resolves Maven and Gradle dependencies without requiring Java, Maven, or Gradle to be installed.

Why Antlers?

  • Fast - Native Rust implementation with parallel downloads
  • No JVM required - Resolve Java dependencies without Java installed
  • Hermetic builds - Reproducible, lockfile-based resolution
  • Multi-ecosystem - Supports Maven Central, Gradle plugins, and custom repositories
  • Migration-friendly - Import settings from Maven, Gradle, npm, pip, and Ivy

Quick Example

# Initialize a new project
antlers init

# Resolve a dependency
antlers resolve org.jetbrains.kotlin:kotlin-stdlib:2.0.0

# Add a repository
antlers add repo jitpack --preset

Features

FeatureDescription
Dependency resolutionTransitive resolution with conflict strategies
Gradle Module MetadataFull .module file support for rich variants
Repository presetsBuilt-in presets across Maven, npm, PyPI, and NuGet
Configuration migrationImport repositories/credentials from settings.xml, settings.gradle, etc.
Lockfile format (library)Read/write lockfiles via antlers-lock (CLI not yet)
Hermetic config (library)Hermetic controls in the Rust API (CLI flags pending)
Credential managementBearer tokens, basic auth, netrc, environment variables

Getting Started

Head to the Installation page to get started, or jump straight to the Quick Start guide.

License

Antlers is dual-licensed under Apache 2.0 and MIT.

Installation

From Source (Cargo)

If you have Rust installed, you can build from source:

cargo install --git https://github.com/albertocavalcante/antlers antlers-cli

Pre-built Binaries

Pre-built binaries are available on the GitHub Releases page for:

  • Linux (x86_64, aarch64)
  • macOS (x86_64, aarch64)
  • Windows (x86_64)

Linux / macOS

# Download the latest release (adjust URL for your platform)
curl -LO https://github.com/albertocavalcante/antlers/releases/latest/download/antlers-linux-x86_64.tar.gz

# Extract
tar xzf antlers-linux-x86_64.tar.gz

# Move to PATH
sudo mv antlers /usr/local/bin/

Windows

Download the .zip file from the releases page and add the extracted directory to your PATH.

Verify Installation

antlers --version

Next Steps

Once installed, head to the Quick Start guide to resolve your first dependency.

Quick Start

This guide will get you resolving JVM dependencies in under 5 minutes.

Initialize a Project

Create a new antlers.toml configuration file:

antlers init

This creates a minimal configuration with Maven Central:

[project]
name = "my-project"
version = "0.1.0"

[[repositories]]
id = "central"
name = "Maven Central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

Note: the CLI currently uses antlers.toml for init, add, show, and fmt. Resolution is driven by CLI arguments, not the file (yet).

Resolve a Dependency

Resolve a single artifact and its transitive dependencies:

antlers resolve org.jetbrains.kotlin:kotlin-stdlib:2.0.0

Output:

✓ org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (3 artifacts)
# org.jetbrains.kotlin:kotlin-stdlib:2.0.0
  org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (abc123...)
  org.jetbrains:annotations:13.0 (def456...)
  org.jetbrains.kotlin:kotlin-stdlib-common:2.0.0 (789...)

Add a Repository

Need artifacts from JitPack, Jenkins, or another repository?

# Add a preset repository
antlers add repo jitpack --preset

# Add a custom repository
antlers add repo mycompany https://maven.mycompany.com/releases/

# Add with authentication
antlers add repo github https://maven.pkg.github.com/org/repo --token-env GITHUB_TOKEN

Different Output Formats

# JSON output
antlers resolve com.google.guava:guava:33.0.0-jre --format json

# Dependency tree
antlers resolve com.google.guava:guava:33.0.0-jre --format tree

# Buck2 build file
antlers resolve com.google.guava:guava:33.0.0-jre --format buck

Import Existing Configuration

Already have Maven or Gradle configured? Import your settings:

# Auto-detect and import from all found configs
antlers init --detect

# Import from a specific file
antlers init --from ~/.m2/settings.xml

This imports repositories and credentials from:

  • Maven settings.xml
  • Gradle settings.gradle / settings.gradle.kts
  • Ivy ivysettings.xml
  • npm .npmrc
  • pip pip.conf

Next Steps

Configuration

Antlers uses a TOML configuration file called antlers.toml. This guide covers common configuration scenarios.

Note: the CLI currently uses antlers.toml for init, add, show, and fmt. resolve and fetch are driven by CLI arguments and do not read the file yet.

Creating a Configuration

The easiest way to create a configuration is with antlers init:

antlers init

This creates a minimal antlers.toml with Maven Central configured.

Adding Repositories

Using the CLI

The easiest way to add repositories:

# Add a preset repository
antlers add repo jitpack --preset

# Add a custom repository
antlers add repo mycompany https://maven.mycompany.com/releases/

Manual Configuration

Edit antlers.toml directly:

[[repositories]]
id = "central"
name = "Maven Central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

[[repositories]]
id = "jitpack"
name = "JitPack"
url = "https://jitpack.io/"

Authentication

Bearer Token (GitHub Packages, etc.)

antlers add repo github https://maven.pkg.github.com/org/repo --token-env GITHUB_TOKEN

Or in antlers.toml:

[[repositories]]
id = "github"
url = "https://maven.pkg.github.com/org/repo"

[repositories.credentials]
type = "bearer"
token = { env = "GITHUB_TOKEN" }

Basic Auth (Artifactory, Nexus, etc.)

[[repositories]]
id = "artifactory"
url = "https://artifactory.example.com/maven"

[repositories.credentials]
type = "basic"
username = { env = "ARTIFACTORY_USER" }
password = { env = "ARTIFACTORY_PASS" }

Environment Variables

Use { env = "VAR_NAME" } to reference environment variables:

[repositories.credentials]
type = "basic"
username = { env = "MAVEN_USER" }
password = { env = "MAVEN_PASS" }

For hermetic builds, explicitly allow the variables:

[env]
allow = ["MAVEN_USER", "MAVEN_PASS"]

Importing from Existing Tools

Auto-Detection

Scan for all existing package manager configurations:

antlers init --detect

This searches for:

  • ~/.m2/settings.xml (Maven)
  • settings.gradle / settings.gradle.kts (Gradle)
  • ~/.ivy2/ivysettings.xml (Ivy)
  • ~/.npmrc, ./.npmrc (npm)
  • ~/.config/pip/pip.conf, ~/.pip/pip.conf (pip)
  • ~/Library/Application Support/pip/pip.conf (pip, macOS)

Specific File

Import from a specific configuration:

antlers init --from ~/.m2/settings.xml
antlers init --from settings.gradle.kts
antlers init --from ~/.ivy2/ivysettings.xml

Formatting

Keep your configuration tidy:

# Format in place
antlers fmt

# Check formatting (useful for CI)
antlers fmt --check

# Preview changes
antlers fmt --diff

Viewing Configuration

# Pretty print
antlers show

# JSON output
antlers show --json

Next Steps

Resolving Dependencies

This guide covers how to resolve JVM dependencies with Antlers.

Note: antlers resolve uses CLI arguments only; it does not read dependencies from antlers.toml yet.

Basic Resolution

Resolve a single artifact:

antlers resolve org.jetbrains.kotlin:kotlin-stdlib:2.0.0

Resolve multiple artifacts:

antlers resolve \
  com.google.guava:guava:33.0.0-jre \
  com.fasterxml.jackson.core:jackson-databind:2.17.0

Artifact Coordinates

Coordinates follow the Maven format: groupId:artifactId:version

Optional classifier and/or extension: groupId:artifactId:version:classifier groupId:artifactId:version@extension groupId:artifactId:version:classifier@extension

Examples:

  • org.jetbrains.kotlin:kotlin-stdlib:2.0.0 - Standard JAR
  • org.jetbrains.kotlin:kotlin-stdlib:2.0.0:sources - Sources JAR
  • org.jetbrains.kotlin:kotlin-stdlib:2.0.0@pom - POM file

Output Formats

Text (Default)

antlers resolve com.google.guava:guava:33.0.0-jre
✓ com.google.guava:guava:33.0.0-jre (15 artifacts)
# com.google.guava:guava:33.0.0-jre
  com.google.guava:guava:33.0.0-jre (abc...)
  com.google.guava:failureaccess:1.0.2 (def...)
  ...

Dependency Tree

antlers resolve com.google.guava:guava:33.0.0-jre --format tree
com.google.guava:guava:33.0.0-jre
├── com.google.guava:failureaccess:1.0.2
├── com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
├── com.google.code.findbugs:jsr305:3.0.2
├── org.checkerframework:checker-qual:3.42.0
├── com.google.errorprone:error_prone_annotations:2.23.0
└── com.google.j2objc:j2objc-annotations:2.8

JSON

antlers resolve com.google.guava:guava:33.0.0-jre --format json
[
  {
    "root": "com.google.guava:guava:33.0.0-jre",
    "artifacts": [
      {
        "coordinate": "com.google.guava:guava:33.0.0-jre",
        "sha256": "abc123...",
        "sha1": "def456...",
        "depth": 0
      }
    ]
  }
]

Buck2 Build File

antlers resolve com.google.guava:guava:33.0.0-jre --format buck
# Generated by antlers

remote_file(
    name = "guava_jar",
    out = "guava-33.0.0-jre.jar",
    sha256 = "abc123...",
    url = "mvn:com.google.guava:guava:jar:33.0.0-jre",
)

prebuilt_jar(
    name = "guava",
    binary_jar = ":guava_jar",
    visibility = ["PUBLIC"],
)

Using Additional Repositories

Preset Repositories

antlers resolve com.github.user:repo:v1.0.0 --preset jitpack

Multiple presets:

antlers resolve some:artifact:1.0.0 --preset jitpack --preset jenkins

Custom Repository URL

antlers resolve com.example:lib:1.0.0 --repo https://maven.example.com/releases/

Transitive Dependencies

By default, transitive dependencies are resolved. To get only direct dependencies:

antlers resolve com.google.guava:guava:33.0.0-jre --transitive false

Gradle Module Metadata

Antlers supports Gradle Module Metadata (.module files) which provide richer dependency information including:

  • Platform-specific variants
  • Feature variants
  • Capability conflicts

To disable GMM and use only POM files:

antlers resolve some:artifact:1.0.0 --pom-only

Saving Output

Write results to a file:

antlers resolve com.google.guava:guava:33.0.0-jre -f json -o deps.json

Conflict Resolution

When multiple versions of the same artifact are found, Antlers uses a conflict strategy:

  • highest-wins (CLI default) - Use the highest version
  • nearest-wins - Use the version nearest to the root
  • strict - Fail on conflicts

The CLI currently always uses highest-wins. To change this, use the Rust API:

#![allow(unused)]
fn main() {
use antlers::Antlers;

let antler = Antlers::with_defaults().nearest_wins();
}

For strict conflict handling, use the lower-level dendro::Resolver with the StrictFails strategy.

Next Steps

Repository Presets

Antlers includes built-in presets for common repositories, so you don't need to remember URLs.

Listing Available Presets

antlers repos list

Filter by ecosystem:

antlers repos list --ecosystem maven

Using Presets

With Resolution

antlers resolve com.github.user:repo:v1.0.0 --preset jitpack

Adding to Configuration

antlers add repo jitpack --preset

This adds the repository to your antlers.toml:

[[repositories]]
id = "jitpack"
name = "JitPack"
url = "https://jitpack.io/"

Available Presets

Maven (JVM)

Preset IDNameURLDescription
centralMaven Centralhttps://repo1.maven.org/maven2/The default Maven repository for open-source artifacts
googleGoogle Mavenhttps://maven.google.com/Android and Google libraries
gradle-pluginsGradle Plugin Portalhttps://plugins.gradle.org/m2/Gradle plugins
jcenterJCenterhttps://jcenter.bintray.com/Deprecated, read-only mirror
sonatype-snapshotsSonatype Snapshotshttps://oss.sonatype.org/content/repositories/snapshots/OSS snapshot builds
sonatype-releasesSonatype Releaseshttps://oss.sonatype.org/content/repositories/releases/OSS releases
sonatype-s01-snapshotsSonatype S01 Snapshotshttps://s01.oss.sonatype.org/content/repositories/snapshots/Newer OSS snapshots
jenkinsJenkinshttps://repo.jenkins-ci.org/public/Jenkins plugins and libraries
jitpackJitPackhttps://jitpack.io/Build JVM artifacts from GitHub
spring-milestonesSpring Milestoneshttps://repo.spring.io/milestone/Spring milestone/RC builds
spring-snapshotsSpring Snapshotshttps://repo.spring.io/snapshot/Spring snapshot builds
atlassianAtlassianhttps://packages.atlassian.com/maven-public/Atlassian public repository
redhat-gaRed Hat GAhttps://maven.repository.redhat.com/ga/Red Hat GA repository
clojarsClojarshttps://repo.clojars.org/Clojure libraries
jbossJBosshttps://repository.jboss.org/nexus/content/groups/public/JBoss community repository
apache-snapshotsApache Snapshotshttps://repository.apache.org/content/repositories/snapshots/Apache snapshot builds
hortonworksHortonworkshttps://repo.hortonworks.com/content/repositories/releases/Hortonworks artifacts
confluentConfluenthttps://packages.confluent.io/maven/Kafka ecosystem artifacts
kotlin-devKotlin Devhttps://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/Kotlin development builds
compose-devCompose Devhttps://maven.pkg.jetbrains.space/public/p/compose/dev/Compose Multiplatform development builds

npm

Preset IDNameURLDescription
npmjsnpm Registryhttps://registry.npmjs.org/Default npm registry
yarnYarn Registryhttps://registry.yarnpkg.com/Yarn registry mirror

PyPI

Preset IDNameURLDescription
pypiPyPIhttps://pypi.org/simple/Python Package Index
testpypiTestPyPIhttps://test.pypi.org/simple/Pre-release testing

NuGet

Preset IDNameURLDescription
nugetNuGet Galleryhttps://api.nuget.org/v3/index.jsonDefault NuGet registry

Preset Suggestions

When resolution fails, Antlers suggests relevant presets based on the group ID:

$ antlers resolve org.jenkins-ci.plugins:git:5.0.0

Error: Failed to resolve org.jenkins-ci.plugins:git:5.0.0

Hint: This artifact may be in the jenkins repository.
Try: antlers resolve org.jenkins-ci.plugins:git:5.0.0 --preset jenkins

Auto-Suggested Presets

Group ID PatternSuggested Preset
org.jenkins-ci.*, io.jenkins.*jenkins
org.gradle.*, com.gradle.*gradle-plugins
org.springframework.* with snapshot in group idspring-snapshots
com.atlassian.*atlassian
com.github.*, io.github.*jitpack
org.clojure.*, clojureclojars
com.redhat.*, org.jboss.*redhat-ga
io.confluent.*confluent

Custom Presets

You can define your own "presets" by adding repositories to your project configuration:

# In antlers.toml
[[repositories]]
id = "mycompany"
name = "My Company Artifactory"
url = "https://artifactory.mycompany.com/maven/"

[repositories.credentials]
type = "basic"
username = { env = "ARTIFACTORY_USER" }
password = { env = "ARTIFACTORY_PASS" }

Next Steps

Migration Guide

Antlers can import repository and credential configurations from other package managers, making it easy to switch from existing tools.

Supported Formats

FormatFileDescription
Mavensettings.xmlServers, mirrors, profiles
Gradlesettings.gradle(.kts)Repository declarations
Ivyivysettings.xmlResolvers, credentials
npm.npmrcRegistry configuration
pippip.confIndex URLs

Quick Migration

Auto-Detection

Scan all standard locations and import everything found:

antlers init --detect

This searches:

  • ~/.m2/settings.xml
  • ./settings.gradle, ./settings.gradle.kts
  • ~/.ivy2/ivysettings.xml
  • ~/.npmrc, ./.npmrc
  • ~/.config/pip/pip.conf, ~/.pip/pip.conf
  • ~/Library/Application Support/pip/pip.conf (macOS)

From Specific File

antlers init --from ~/.m2/settings.xml
antlers init --from settings.gradle.kts
antlers init --from ~/.ivy2/ivysettings.xml

What Gets Migrated

Repositories

  • Repository URLs
  • Repository IDs and names
  • Ecosystem type (Maven, npm, etc.)

Credentials

  • Username/password (basic auth)
  • Tokens (bearer auth)
  • Environment variable references

Environment Variables

  • Patterns like ${env.VAR_NAME} are preserved
  • Migrated variables are added to [env].allow

Post-Migration

After migration, review the generated antlers.toml:

antlers show

Format for consistency:

antlers fmt

Detailed Guides

Migrating from Maven

This guide covers migrating from Maven's settings.xml to Antlers.

Quick Start

antlers init --from ~/.m2/settings.xml

What Gets Migrated

Servers

Maven servers with credentials become Antlers repositories:

Maven settings.xml:

<settings>
    <servers>
        <server>
            <id>github</id>
            <username>myuser</username>
            <password>mytoken</password>
        </server>
    </servers>
</settings>

Antlers antlers.toml:

[[repositories]]
id = "github"
name = "Server: github"
url = "https://github.example.com/"  # Placeholder - update manually

[repositories.credentials]
type = "basic"
username = "myuser"
password = "mytoken"

Mirrors

Maven mirrors are imported as repositories:

Maven:

<mirrors>
    <mirror>
        <id>artifactory</id>
        <name>Artifactory Mirror</name>
        <url>https://artifactory.example.com/maven</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>

Antlers:

[[repositories]]
id = "artifactory"
name = "Artifactory Mirror"
url = "https://artifactory.example.com/maven"
ecosystem = "maven"

Profile Repositories

Repositories defined in profiles are imported:

Maven:

<profiles>
    <profile>
        <id>dev</id>
        <repositories>
            <repository>
                <id>company-releases</id>
                <name>Company Releases</name>
                <url>https://nexus.company.com/releases</url>
            </repository>
        </repositories>
    </profile>
</profiles>

Antlers:

[[repositories]]
id = "company-releases"
name = "Company Releases"
url = "https://nexus.company.com/releases"
ecosystem = "maven"

Environment Variables

Maven's ${env.VAR} syntax is preserved:

Maven:

<server>
    <id>github</id>
    <username>${env.GITHUB_USER}</username>
    <password>${env.GITHUB_TOKEN}</password>
</server>

Antlers:

[[repositories]]
id = "github"

[repositories.credentials]
type = "basic"
username = { env = "GITHUB_USER" }
password = { env = "GITHUB_TOKEN" }

[env]
allow = ["GITHUB_USER", "GITHUB_TOKEN"]

Manual Adjustments

After migration, you may need to:

  1. Add repository URLs - Servers without matching mirrors/repositories get placeholder URLs
  2. Remove duplicates - If the same repository appears in multiple places
  3. Update credentials - Replace inline passwords with environment variables

Comparison

Maven ConceptAntlers Equivalent
<server>[repositories.credentials]
<mirror>[[repositories]]
<repository>[[repositories]]
${env.VAR}{ env = "VAR" }
settings.xmlantlers.toml

Migrating from Gradle

This guide covers migrating from Gradle's settings.gradle or settings.gradle.kts to Antlers.

Quick Start

antlers init --from settings.gradle.kts

What Gets Migrated

Maven Repositories

Gradle maven { } blocks are imported:

Gradle (Kotlin DSL):

dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven {
            url = uri("https://maven.example.com/releases")
        }
    }
}

Antlers:

[[repositories]]
id = "central"
name = "Maven Central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

[[repositories]]
id = "maven-1"
url = "https://maven.example.com/releases"
ecosystem = "maven"

Well-Known Repositories

Gradle shortcuts are recognized:

GradleAntlers Equivalent
mavenCentral()Maven Central
google()Google Maven
gradlePluginPortal()Gradle Plugin Portal
jcenter()JCenter (deprecated, read-only)
mavenLocal()Maven Local (file://~/.m2/repository/)

Authenticated Repositories

Gradle:

maven {
    url = uri("https://maven.pkg.github.com/org/repo")
    credentials {
        username = System.getenv("GITHUB_USER")
        password = System.getenv("GITHUB_TOKEN")
    }
}

Antlers:

[[repositories]]
id = "maven-1"
url = "https://maven.pkg.github.com/org/repo"

[repositories.credentials]
type = "basic"
username = { env = "GITHUB_USER" }
password = { env = "GITHUB_TOKEN" }

[env]
allow = ["GITHUB_USER", "GITHUB_TOKEN"]

Groovy DSL

Both Kotlin and Groovy DSL are supported:

Gradle (Groovy):

dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven {
            url 'https://maven.example.com/releases'
        }
    }
}

Limitations

The parser is line-based and does not evaluate Gradle logic. Review the output, especially when repositories are built dynamically or conditionally. Credentials are attached to the most recent repository block, and pluginManagement and dependencyResolutionManagement repositories are both scanned. Dependencies and version catalogs are not migrated.

Comparison

Gradle ConceptAntlers Equivalent
maven { url = ... }[[repositories]]
credentials { }[repositories.credentials]
System.getenv(){ env = "..." }
settings.gradle(.kts)antlers.toml

Migrating from Ivy

This guide covers migrating from Apache Ivy's ivysettings.xml to Antlers.

Quick Start

antlers init --from ~/.ivy2/ivysettings.xml

What Gets Migrated

Ibiblio Resolvers

Maven-compatible resolvers are imported:

Ivy:

<ivysettings>
    <resolvers>
        <ibiblio name="central" m2compatible="true" root="https://repo1.maven.org/maven2/"/>
        <ibiblio name="jitpack" root="https://jitpack.io/"/>
    </resolvers>
</ivysettings>

Antlers:

[[repositories]]
id = "central"
name = "central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

[[repositories]]
id = "jitpack"
name = "jitpack"
url = "https://jitpack.io/"
ecosystem = "maven"

Chain Resolvers

Resolvers inside chains are flattened:

Ivy:

<resolvers>
    <chain name="main">
        <ibiblio name="central" root="https://repo1.maven.org/maven2/"/>
        <ibiblio name="private" root="https://maven.example.com/"/>
    </chain>
</resolvers>

Antlers:

[[repositories]]
id = "central"
url = "https://repo1.maven.org/maven2/"

[[repositories]]
id = "private"
url = "https://maven.example.com/"

Credentials

Ivy credentials are matched to resolvers by host:

Ivy:

<ivysettings>
    <credentials host="maven.example.com" username="myuser" passwd="mytoken"/>
    <resolvers>
        <ibiblio name="private" root="https://maven.example.com/repo/"/>
    </resolvers>
</ivysettings>

Antlers:

[[repositories]]
id = "private"
url = "https://maven.example.com/repo/"

[repositories.credentials]
type = "basic"
username = "myuser"
password = "mytoken"

Environment Variables

Ivy's ${env.VAR} pattern is preserved:

Ivy:

<credentials host="maven.example.com"
             username="${env.MAVEN_USER}"
             passwd="${env.MAVEN_PASS}"/>

Antlers:

[repositories.credentials]
type = "basic"
username = { env = "MAVEN_USER" }
password = { env = "MAVEN_PASS" }

[env]
allow = ["MAVEN_USER", "MAVEN_PASS"]

Default Repository

If an ibiblio resolver has no root attribute, Maven Central is used:

Ivy:

<ibiblio name="central" m2compatible="true"/>

Antlers:

[[repositories]]
id = "central"
url = "https://repo1.maven.org/maven2/"

Unsupported Features

The following Ivy features are not migrated:

  • <url> resolvers with custom patterns (partially supported)
  • <filesystem> resolvers
  • <sftp> and other transport resolvers
  • Ivy-specific artifact patterns

Comparison

Ivy ConceptAntlers Equivalent
<ibiblio>[[repositories]]
<chain>(flattened to individual repos)
<credentials>[repositories.credentials]
${env.VAR}{ env = "VAR" }
ivysettings.xmlantlers.toml

CLI Reference

Complete reference for all antlers commands.

Global Options

-v, --verbose    Enable verbose logging
-h, --help       Print help
-V, --version    Print version

antlers init

Initialize a new antlers.toml configuration file.

antlers init [OPTIONS]

Options

OptionDescription
--from <FILE>Import from a specific config file
--detectAuto-detect and import from all found package manager configs
-o, --output <PATH>Output path (default: antlers.toml)
--forceOverwrite existing file

Examples

# Create minimal config
antlers init

# Import from Maven settings
antlers init --from ~/.m2/settings.xml

# Auto-detect all configs
antlers init --detect

antlers resolve

Resolve dependencies for one or more artifacts.

antlers resolve [OPTIONS] <ARTIFACTS>...

Arguments

ArgumentDescription
<ARTIFACTS>Artifact coordinates (e.g., group:artifact:version)

Options

OptionDescription
-t, --transitiveResolve transitive dependencies (default: true)
-f, --format <FORMAT>Output format: text, json, tree, buck (Buck2)
-o, --output <FILE>Write output to file
--repo <URL>Additional repository URL
-p, --preset <NAME>Use a preset repository
--pom-onlyDisable Gradle Module Metadata

Examples

# Basic resolution
antlers resolve org.jetbrains.kotlin:kotlin-stdlib:2.0.0

# Multiple artifacts
antlers resolve com.google.guava:guava:33.0.0-jre com.fasterxml.jackson.core:jackson-databind:2.17.0

# With preset repository
antlers resolve com.github.user:repo:v1.0.0 --preset jitpack

# JSON output to file
antlers resolve com.google.guava:guava:33.0.0-jre -f json -o deps.json

# Dependency tree
antlers resolve org.springframework.boot:spring-boot-starter:3.2.0 -f tree

antlers add repo

Add a repository to antlers.toml.

antlers add repo [OPTIONS] <ID> [URL]

Arguments

ArgumentDescription
<ID>Repository ID (used as key in config)
[URL]Repository URL (not needed with --preset)

Options

OptionDescription
-p, --presetUse a preset repository (ID becomes preset name)
--name <NAME>Display name for the repository
--ecosystem <ECO>Ecosystem: maven, npm, pypi, nuget (default: maven)
--token-env <VAR>Environment variable for bearer token auth
-c, --config <PATH>Path to antlers.toml (default: antlers.toml)

Examples

# Add a preset
antlers add repo jitpack --preset

# Add custom repository
antlers add repo mycompany https://maven.mycompany.com/releases/

# With authentication
antlers add repo github https://maven.pkg.github.com/org/repo --token-env GITHUB_TOKEN

# Different ecosystem
antlers add repo npm-private https://npm.mycompany.com/ --ecosystem npm

antlers fetch

Download an artifact (verifies checksums when available).

antlers fetch [OPTIONS] <ARTIFACT>

Options

OptionDescription
-o, --output <DIR>Output directory (default: .)
--sourcesAlso fetch sources JAR
--javadocAlso fetch javadoc JAR

Examples

# Download artifact
antlers fetch org.jetbrains.kotlin:kotlin-stdlib:2.0.0

# With sources and javadoc
antlers fetch org.jetbrains.kotlin:kotlin-stdlib:2.0.0 --sources --javadoc

# To specific directory
antlers fetch org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -o ./libs

antlers info

Display information about an artifact coordinate.

antlers info <ARTIFACT>

Examples

antlers info org.jetbrains.kotlin:kotlin-stdlib:2.0.0

Output:

Artifact Information
==================================================
Group ID:    org.jetbrains.kotlin
Artifact ID: kotlin-stdlib
Version:     2.0.0
Extension:   jar

Repository path: org/jetbrains/kotlin/kotlin-stdlib/2.0.0/kotlin-stdlib-2.0.0.jar
POM path:        org/jetbrains/kotlin/kotlin-stdlib/2.0.0/kotlin-stdlib-2.0.0.pom

antlers show

Display the current configuration.

antlers show [OPTIONS] [PATH]

Options

OptionDescription
--jsonOutput as JSON

Examples

# Show config
antlers show

# JSON output
antlers show --json

# Specific file
antlers show /path/to/antlers.toml

antlers fmt

Format antlers.toml with canonical ordering.

antlers fmt [OPTIONS] [PATH]

Options

OptionDescription
--checkCheck if formatted (exit 1 if not)
--diffShow diff without writing

Examples

# Format in place
antlers fmt

# Check only (for CI)
antlers fmt --check

# Show diff
antlers fmt --diff

antlers repos [list]

List available repository presets. antlers repos is equivalent to antlers repos list.

antlers repos [list] [OPTIONS]

Options

OptionDescription
-e, --ecosystem <ECO>Filter by ecosystem

Examples

# List all presets
antlers repos list

# Maven only
antlers repos list --ecosystem maven

antlers.toml Reference

Complete reference for the antlers.toml configuration file format.

Status

The CLI currently uses antlers.toml for init, add, show, and fmt. resolve and fetch are driven by CLI arguments and do not read the file yet. The schema below is intended for tooling and library integrations.

Overview

[project]
name = "my-project"
version = "1.0.0"
description = "My JVM project"

[[repositories]]
id = "central"
name = "Maven Central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

[[repositories]]
id = "github"
name = "GitHub Packages"
url = "https://maven.pkg.github.com/org/repo"

[repositories.credentials]
type = "bearer"
token = { env = "GITHUB_TOKEN" }

[dependencies]
"com.google.guava:guava" = "33.0.0-jre"
"org.jetbrains.kotlin:kotlin-stdlib" = "2.0.0"

[dev-dependencies]
"org.junit.jupiter:junit-jupiter" = "5.10.0"

[build-dependencies]
"org.jetbrains.kotlin:kotlin-gradle-plugin" = "2.0.0"

[constraints]
"com.fasterxml.jackson:jackson-bom" = { version = "2.16.0", type = "bom" }

[exclusions]
"commons-logging:commons-logging" = "*"

[resolver]
conflict-strategy = "highest-wins"
transitive = true

[cache]
path = ".antlers/cache"
mode = "read-write"

[network]
offline = false
connect-timeout = 30
max-connections = 16

[env]
allow = ["GITHUB_TOKEN", "MAVEN_USER", "MAVEN_PASS"]

[output]
lockfile = "antlers.lock.json"
require-sha256 = true

[project]

Project metadata. Optional but recommended.

FieldTypeDescription
namestringProject name
versionstringProject version
descriptionstringProject description
[project]
name = "my-project"
version = "1.0.0"
description = "A sample JVM project"

[[repositories]]

Repository configuration. Order matters for priority.

FieldTypeRequiredDescription
idstringYesUnique identifier
urlstringYesRepository URL
namestringNoDisplay name
ecosystemstringNomaven, npm, pypi, nuget (default: maven)
credentialstableNoAuthentication configuration

Basic Repository

[[repositories]]
id = "central"
name = "Maven Central"
url = "https://repo1.maven.org/maven2/"
ecosystem = "maven"

With Bearer Token

[[repositories]]
id = "github"
url = "https://maven.pkg.github.com/org/repo"

[repositories.credentials]
type = "bearer"
token = { env = "GITHUB_TOKEN" }

With Basic Auth

[[repositories]]
id = "artifactory"
url = "https://artifactory.example.com/maven"

[repositories.credentials]
type = "basic"
username = { env = "ARTIFACTORY_USER" }
password = { env = "ARTIFACTORY_PASS" }
[repositories.credentials]
type = "basic"
username = "myuser"
password = "mypassword"  # Avoid committing secrets!

Netrc Authentication

[repositories.credentials]
type = "netrc"

[dependencies]

Dependencies to resolve. Keys are group:artifact coordinates.

Simple Version

[dependencies]
"com.google.guava:guava" = "33.0.0-jre"
"org.jetbrains.kotlin:kotlin-stdlib" = "2.0.0"

Detailed Specification

[dependencies]
"com.google.guava:guava" = { version = "33.0.0-jre", classifier = "jdk8" }
"org.apache.logging.log4j:log4j-core" = { version = "2.23.0", exclusions = ["org.apache.logging.log4j:log4j-api"] }

Detailed fields:

FieldTypeDescription
versionstringRequired version requirement
scopestringMaven scope (compile, runtime, test, provided)
classifierstringClassifier (e.g., sources, javadoc)
typestringArtifact type/extension (e.g., jar, pom)
exclusionsarrayTransitive exclusions (group:artifact)
transitiveboolWhether to include transitive deps (default: true)

[dev-dependencies]

Development-only dependencies. Same format as [dependencies].

[dev-dependencies]
"org.junit.jupiter:junit-jupiter" = "5.10.0"
"org.mockito:mockito-core" = "5.10.0"

[build-dependencies]

Build-time dependencies. Same format as [dependencies].

[build-dependencies]
"org.jetbrains.kotlin:kotlin-gradle-plugin" = "2.0.0"

[constraints]

Version constraints (BOMs, platform constraints). Keys are group:artifact.

[constraints]
"com.fasterxml.jackson:jackson-bom" = { version = "2.16.0", type = "bom" }
"org.springframework:spring-framework-bom" = { version = "6.1.5", type = "platform" }

Constraint fields:

FieldTypeDescription
versionstringRequired version
typestringbom or platform

[exclusions]

Global exclusions applied to all dependencies.

[exclusions]
"commons-logging:commons-logging" = "*"
"log4j:log4j" = "2.0.0"

[resolver]

Resolution behavior configuration.

FieldTypeDefaultDescription
conflict-strategystringhighest-winshighest-wins, nearest-wins, strict
transitivebooltrueResolve transitive dependencies
[resolver]
conflict-strategy = "highest-wins"
transitive = true

Conflict Strategies

  • highest-wins - Use highest version when conflicts occur (Gradle/Coursier-like)
  • nearest-wins - Use version from nearest dependency in tree (Maven-like)
  • strict - Fail on any version conflict

[cache]

Caching configuration.

FieldTypeDefaultDescription
pathstringOS defaultCache directory path
modestringread-writeread-write, read-only, disabled
[cache]
path = ".antlers/cache"
mode = "read-write"

[network]

Network behavior configuration.

FieldTypeDescription
offlineboolDisable network access
connect-timeoutintConnection timeout in seconds
max-connectionsintMaximum concurrent connections
[network]
offline = false
connect-timeout = 30
max-connections = 16

[env]

Environment variable configuration for hermetic workflows.

FieldTypeDescription
allowarrayEnvironment variables that can be used
[env]
allow = ["GITHUB_TOKEN", "MAVEN_USER", "MAVEN_PASS"]

[output]

Output configuration used by tooling/integrations.

FieldTypeDescription
lockfilestringLockfile path
require-sha256boolRequire SHA-256 checksums in outputs
[output]
lockfile = "antlers.lock.json"
require-sha256 = true

Environment Variables

This page documents environment variables that affect Antlers behavior.

Credential Variables

Reference environment variables in credentials using { env = "VAR_NAME" }:

[repositories.credentials]
type = "basic"
username = { env = "MAVEN_USER" }
password = { env = "MAVEN_PASS" }

Common Variables

VariableDescription
GITHUB_TOKENGitHub Packages authentication
GITLAB_TOKENGitLab Packages authentication
ARTIFACTORY_USERArtifactory username
ARTIFACTORY_PASSArtifactory password
NEXUS_USERNexus username
NEXUS_PASSNexus password

Allowed Variables

For hermetic workflows, explicitly allow variables:

[env]
allow = ["GITHUB_TOKEN", "MAVEN_USER", "MAVEN_PASS"]

When [env].allow is set, only listed variables can be referenced in credentials. This is enforced by AntlersToml::validate_hermetic() or by integrations that choose to enforce hermetic rules; the CLI does not enforce it yet.

Proxy Configuration

Antlers uses reqwest, which enables system proxy settings by default. The following environment variables are honored by the HTTP client:

VariableDescription
HTTP_PROXY / http_proxyHTTP proxy URL
HTTPS_PROXY / https_proxyHTTPS proxy URL
ALL_PROXY / all_proxyProxy for both HTTP and HTTPS
NO_PROXY / no_proxyComma-separated list of hosts to bypass

Example:

export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,internal.example.com
antlers resolve com.google.guava:guava:33.0.0-jre

Netrc

When using type = "netrc" credentials, the netrc file path can be overridden with:

VariableDescription
NETRCPath to netrc file

Hermetic Builds

Hermetic builds ensure reproducibility by eliminating external dependencies and non-determinism. In Antlers today, hermetic controls are available in the Rust API and in configuration validation. The CLI does not enforce hermetic behavior yet.

Hermetic Levels (Rust API)

The antlers::config::HermeticConfig supports three levels:

  • Disabled - No hermetic guarantees
  • Reproducible - Deterministic output, but network/env access allowed
  • Strict - No network, explicit cache path, strict environment controls

Using the Rust API

#![allow(unused)]
fn main() {
use antlers::config::{AntlerConfig, CacheConfig};

// Strict hermetic configuration for build systems
let config = AntlerConfig::hermetic()
    .with_cache(CacheConfig::read_only("/sandbox/cache"));

config.validate()?;
}

Validating antlers.toml

The TOML schema does not include a [hermetic] section. If you want to enforce hermetic rules in tooling, use AntlersToml::validate_hermetic() to check for:

  • An explicit cache path
  • An environment allowlist that covers any referenced env vars
#![allow(unused)]
fn main() {
use antlers::AntlersToml;

let config = AntlersToml::load("antlers.toml")?;
config.validate_hermetic()?;
}

Lockfiles

Antlers provides the antlers-lock crate for lockfile generation and compatibility with rules_jvm_external:

#![allow(unused)]
fn main() {
use antlers_lock::from_resolution;

let lockfile = from_resolution(&resolution);
lockfile.write_file("antlers.lock.json")?;
}

CLI lockfile commands are not available yet; see the Roadmap.

Caching

The current CLI does not persist an on-disk cache; it fetches artifacts on request each run. Caching primitives exist in the Rust API for integrations.

Library Usage

The gather::Fetcher supports optional caches:

#![allow(unused)]
fn main() {
use antlers::{Fetcher, FileCache, RepositoryList};

let cache = FileCache::new("/tmp/antlers-cache")?;
let fetcher = Fetcher::new(RepositoryList::with_defaults())
    .with_cache(cache);
}

Hermetic Integrations

For build system integrations, use CacheConfig to define explicit, hermetic cache paths:

#![allow(unused)]
fn main() {
use antlers::config::CacheConfig;

let cache = CacheConfig::read_only("/sandbox/cache");
}

CLI cache management commands are not available yet; see the Roadmap.

Roadmap

This is a forward-looking list of ideas. Nothing here is implemented in the current CLI unless stated elsewhere in the docs.

CLI

  • Lockfile commands (generate/update/read) backed by antlers-lock.
  • Cache management commands and on-disk caching for the resolver.
  • antlers resolve reading antlers.toml dependencies and resolver settings.
  • Hermetic/offline flags and explicit network controls.
  • Shell completion generation.

Outputs and Integration

  • Bazel-compatible output from the CLI (via antlers-lock V2 writer).
  • More structured output formats for build system consumption.
  • Expanded migration discovery (including Windows pip.ini).