Exploring Maven API Modules for Developers: A Complete Guide to Maven 4's Modular Architecture

Apache Maven 4 re-architected its codebase into discrete API modules that provide a stable, versioned surface for tool and plugin developers, allowing compilation against lightweight artifacts without pulling in the heavy Maven runtime.

Exploring Maven API modules for developers reveals how Maven 4 addresses long-standing extensibility challenges through a clean separation between public contracts and internal implementation. The apache/maven repository organizes these modules under the top-level api/ directory, each distributed as an independent artifact following the naming convention org.apache.maven:maven-api-<module>. This modular design ensures that third-party tools can depend on specific functional areas—such as model parsing or dependency resolution—without inheriting the full execution environment.

Maven API Module Catalog

Maven 4 exposes eleven distinct API modules, each targeting a specific domain of the build lifecycle. These modules form a directed acyclic graph where higher-level APIs depend only on lower-level contracts, never on implementation code.

Core Model and Configuration APIs

Execution and Plugin APIs

Infrastructure and Service Provider APIs

Dependency Architecture and Binary Compatibility

The pom.xml in the api/ directory defines a strict dependency hierarchy: each module declares dependencies only on other API modules, never on implementation modules located in impl/. This guarantees that consuming a single artifact like maven-api-model does not transitively pull in the Maven runtime, XML parsers, or logging frameworks.

Binary compatibility across Maven 4 minor releases is enforced by the japicmp-maven-plugin configured in the parent POM. This ensures that public methods and classes remain stable, allowing tools compiled against Maven 4.0.0 to function correctly with Maven 4.9.9 without recompilation.

Practical Implementation Patterns

Parsing a POM via the SPI

To parse a POM file into a Model object, obtain the ModelParser service implementation and invoke the parse method:

import org.apache.maven.api.model.Model;
import org.apache.maven.api.spi.ModelParser;
import java.nio.file.Path;
import java.nio.file.Paths;

Path pom = Paths.get("pom.xml");
ModelParser parser = lookup(ModelParser.class);  // SPI lookup via maven-api-di
Model model = parser.parse(pom, ModelParser.Mode.DEFAULT);

Walking Dependency Trees

Once parsed, the Model provides immutable accessors for inspecting dependencies:

model.getDependencies().stream()
    .filter(d -> "compile".equals(d.getScope()))
    .forEach(d -> System.out.println(
        d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getVersion()
    ));

Resolving Version Ranges

The VersionResolver SPI converts version ranges into concrete artifacts:

import org.apache.maven.api.VersionRange;
import org.apache.maven.api.Version;
import org.apache.maven.api.spi.VersionRangeResolver;

VersionRangeResolver vrResolver = lookup(VersionRangeResolver.class);
VersionRange range = VersionRange.createFromString("[1.0,2.0)");
Version resolved = vrResolver.resolve(range, repositorySystemSession);

Generating XML Fragments

Use XmlService for lightweight XML manipulation without external libraries:

import org.apache.maven.api.xml.XmlService;
import org.apache.maven.api.xml.XmlNode;

XmlService xml = lookup(XmlService.class);
XmlNode node = xml.createElement("message")
                  .addContent(xml.createText("Hello Maven API"));
System.out.println(node.toString());

Embedding the Maven CLI

For tools requiring full build execution, embed the CLI programmatically:

import org.apache.maven.api.cli.MavenCli;

MavenCli cli = new MavenCli();
int exitCode = cli.doMain(
    new String[] {"verify"}, 
    projectRoot.toString(), 
    System.out, 
    System.err
);

Note: All lookup() calls resolve through Maven's lightweight DI container defined in maven-api-di.

Summary

  • Maven 4's API modules reside under api/ and provide stable contracts for tool development without runtime dependencies.
  • Eleven modules cover annotations, models, settings, toolchains, plugins, XML, DI, metadata, SPI, CLI, and core services.
  • Strict dependency rules prevent API modules from referencing implementation code, ensuring lightweight consumption.
  • Binary compatibility is enforced via japicmp-maven-plugin across minor releases.
  • SPI patterns allow developers to parse POMs, resolve versions, and execute builds through clean interfaces like ModelParser and MavenCli.

Frequently Asked Questions

What is the difference between Maven API modules and implementation modules?

API modules (located in api/) contain only interfaces, annotations, and POJOs that define contracts, while implementation modules (located in impl/) provide the concrete logic for parsing, resolving, and executing builds. Developers should compile against API modules to avoid coupling their code to internal implementation details that may change between releases.

How do I add Maven API modules to my project?

Add the specific API artifact to your Maven dependencies using the coordinates org.apache.maven:maven-api-<module>:<version>, for example:

<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-api-model</artifactId>
    <version>4.0.0</version>
</dependency>

All API modules share the same version number as the Maven release, defined by ${project.version} in the parent POM.

Are Maven API modules backward compatible?

Yes, Maven 4 API modules maintain binary compatibility across minor releases. The japicmp-maven-plugin configuration in the parent pom.xml enforces this by comparing current artifacts against baselines, ensuring that public methods and classes remain unchanged or only extended in backward-compatible ways.

Can I implement custom SPIs for Maven?

Absolutely. The maven-api-spi module defines extension points such as ModelParser, VersionResolver, and transport layers. By implementing these interfaces and registering them through Maven's DI system (using annotations from maven-api-di), you can override default behaviors for POM parsing, version resolution, or artifact transport without modifying Maven's core implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →