# How Maven API Modules Are Organized in Apache Maven 4

> Discover how Maven API modules are organized in Apache Maven 4. Explore eleven focused, loosely-coupled modules under the top-level api directory, each with distinct responsibilities.

- Repository: [The Apache Software Foundation/maven](https://github.com/apache/maven)
- Tags: architecture
- Published: 2026-07-06

---

**The Maven 4 API is organized into eleven focused, loosely-coupled modules under the top-level `api` directory, each defining distinct parts of the public contract—from annotations and XML handling to core types and service-provider interfaces—declaring their own Maven coordinates and assembled by the `maven-api` parent POM.**

The Apache Maven 4 codebase introduces a completely redesigned API structure that replaces the monolithic approach of previous versions. Understanding how **Maven API modules** are organized is essential for plugin developers and tooling authors who need to interact with Maven's immutable public contract. The new architecture splits functionality into discrete JAR artifacts under the `api` directory, with the parent POM at [`api/pom.xml`](https://github.com/apache/maven/blob/main/api/pom.xml) declaring the exact module order to prevent circular dependencies.

## The Hierarchical Structure of Maven API Modules

The eleven Maven API modules are declared in the `<modules>` section of the parent POM at [`api/pom.xml`](https://github.com/apache/maven/blob/main/api/pom.xml) (lines 34-46), ensuring each module compiles only after its dependencies are built. This declaration order reflects a strict layering strategy: foundational utilities form the base, immutable data models build upon them, and high-level services consume both. The hierarchy prevents circular references and guarantees that downstream consumers can depend on thin, specific artifacts rather than the entire API surface.

## Foundation Layer: Annotations, DI, and XML

### maven-api-annotations

The base of the dependency graph is `maven-api-annotations`, containing marker annotations defined in `org.apache.maven.api.annotations`. Key files include [`ThreadSafe.java`](https://github.com/apache/maven/blob/main/ThreadSafe.java) and [`Nonnull.java`](https://github.com/apache/maven/blob/main/Nonnull.java), which supply compile-time nullability and threading contracts used throughout the codebase. No other Maven API module depends on it implicitly; it is the leaf of the dependency graph that all other modules import.

### maven-api-di

The `maven-api-di` module provides lightweight dependency-injection utilities in the `org.apache.maven.api.di` package. The central class is [`ServiceLocator.java`](https://github.com/apache/maven/blob/main/ServiceLocator.java), which implements an annotation-driven service locator pattern. This module depends only on `maven-api-annotations` and is used by most API services to resolve implementation instances at runtime.

### maven-api-xml

Found in [`org.apache.maven.api.xml`](https://github.com/apache/maven/blob/main/org.apache.maven.api.xml), the `maven-api-xml` module defines an immutable XML abstraction consisting of [`XmlNode.java`](https://github.com/apache/maven/blob/main/XmlNode.java) and [`XmlService.java`](https://github.com/apache/maven/blob/main/XmlService.java). These types provide raw XML access for the model parser and plugins without exposing mutable DOM structures. It depends solely on `maven-api-annotations`.

## Data Model Layer: Immutable Configuration Types

### maven-api-model

The `maven-api-model` module contains the immutable representation of the Project Object Model (POM) in `org.apache.maven.api.model`. Generated from Modello MDO files, key classes include [`Model.java`](https://github.com/apache/maven/blob/main/Model.java) and [`Build.java`](https://github.com/apache/maven/blob/main/Build.java), replacing the mutable `org.apache.maven.model` from previous versions. This module depends on both `maven-api-annotations` and `maven-api-xml`.

### maven-api-plugin

Located in `org.apache.maven.api.plugin`, this module describes plugins and their mojos through immutable types like [`PluginDescriptor.java`](https://github.com/apache/maven/blob/main/PluginDescriptor.java) and [`MojoDescriptor.java`](https://github.com/apache/maven/blob/main/MojoDescriptor.java). It depends on `maven-api-annotations` and `maven-api-model`.

### maven-api-settings

The `maven-api-settings` module provides an immutable representation of [`settings.xml`](https://github.com/apache/maven/blob/main/settings.xml) through [`Settings.java`](https://github.com/apache/maven/blob/main/Settings.java) and [`Server.java`](https://github.com/apache/maven/blob/main/Server.java) in `org.apache.maven.api.settings`. It depends only on `maven-api-annotations`.

### maven-api-toolchain

Found in `org.apache.maven.api.toolchain`, this module holds toolchain configuration (e.g., JDK selectors) via [`Toolchain.java`](https://github.com/apache/maven/blob/main/Toolchain.java). It depends on `maven-api-annotations`.

### maven-api-metadata

The `maven-api-metadata` module defines repository metadata types like [`Metadata.java`](https://github.com/apache/maven/blob/main/Metadata.java) in `org.apache.maven.api.metadata`, similar to the legacy `org.apache.maven.artifact.repository.metadata.Metadata`. It depends on `maven-api-annotations`.

## Service and Extension Layer

### maven-api-core

The `maven-api-core` module is the central aggregation point located in `org.apache.maven.api`. It provides high-level immutable types like [`Project.java`](https://github.com/apache/maven/blob/main/Project.java) (lines 30-78), [`ProducedArtifact.java`](https://github.com/apache/maven/blob/main/ProducedArtifact.java), and [`DependencyCoordinates.java`](https://github.com/apache/maven/blob/main/DependencyCoordinates.java), along with core service interfaces. According to the POM at [`maven-api-core/pom.xml`](https://github.com/apache/maven/blob/main/maven-api-core/pom.xml) (lines 33-62), this module depends on all other API modules: annotations, DI, XML, model, settings, toolchain, plugin, and metadata. It serves as the primary dependency for consumers who need the complete immutable model.

### maven-api-spi

The `maven-api-spi` module defines Service-Provider Interfaces in `org.apache.maven.api.spi` that decouple the immutable API from concrete implementations. Key files include [`ModelParser.java`](https://github.com/apache/maven/blob/main/ModelParser.java) and [`ProjectBuilder.java`](https://github.com/apache/maven/blob/main/ProjectBuilder.java). This module depends on `maven-api-core`, `maven-api-di`, and `maven-api-model`, allowing Maven 3 or Maven 4 runtimes to provide their own implementations of these contracts.

### maven-api-cli

Finally, `maven-api-cli` provides minimal command-line entry point helpers in `org.apache.maven.api.cli`, primarily through [`MavenCLI.java`](https://github.com/apache/maven/blob/main/MavenCLI.java). This module depends on `maven-api-core` and `maven-api-spi`, making it useful for embedding Maven programmatically without the full launcher infrastructure.

## Practical Usage: Working Across Maven API Modules

When building tools against the Maven 4 API, you typically interact with multiple modules through the DI layer. The `ServiceLocator` from `maven-api-di` resolves SPI implementations from `maven-api-spi`, while working with immutable types from `maven-api-core` and `maven-api-model`:

```java
// Obtain a ServiceLocator (DI) – the entry point for any Maven API user
ServiceLocator locator = ServiceLocator.lookup();

// Acquire a ProjectBuilder SPI implementation (provided by the Maven runtime)
ProjectBuilder builder = locator.lookup(ProjectBuilder.class);

// Build a Project from a pom.xml file (immutable Project)
Path pom = Paths.get("/my/project/pom.xml");
Project project = builder.build(pom);

// Access model data without mutating anything
Model model = project.getModel();
String javaVersion = model.getProperties().get("maven.compiler.source");

// Retrieve the main artifact (if any)
Optional<ProducedArtifact> mainArtifact = project.getMainArtifact();
mainArtifact.ifPresent(a -> System.out.println("Main artifact: " + a.getPath()));

```

This code uses the `ServiceLocator` from `maven-api-di`, the `ProjectBuilder` SPI from `maven-api-spi`, and the immutable `Project` and `Model` types from `maven-api-core` and `maven-api-model`.

## Summary

- **Maven API modules** are strictly layered into eleven artifacts under the `api` directory, preventing circular dependencies through the build order declared in [`api/pom.xml`](https://github.com/apache/maven/blob/main/api/pom.xml).
- The architecture separates concerns: **annotations** provide contracts, **DI** provides wiring, **XML** provides parsing, **model** provides POM representation, and **core** provides high-level services.
- **SPI modules** (`maven-api-spi`) decouple the API from implementations, allowing Maven 4 to provide runtime-specific behavior while keeping the contract stable.
- All types are **immutable**, making the API safe for concurrent plugin execution and embedding.
- Consumers should depend on `maven-api-core` for general use, or specific modules (like `maven-api-model`) for lightweight tooling.

## Frequently Asked Questions

### What is the purpose of maven-api-core in Maven 4?

The `maven-api-core` module aggregates all other Maven API modules to provide the central immutable types and high-level service interfaces. It contains [`Project.java`](https://github.com/apache/maven/blob/main/Project.java) (lines 30-78) and declares dependencies on all other API modules in its POM (lines 33-62), serving as the primary entry point for consumers who need the complete Maven object model.

### How does maven-api-spi differ from maven-api-core?

While `maven-api-core` defines the immutable data types and service interfaces that consumers use, `maven-api-spi` defines the Service-Provider Interfaces that implementations must provide. The SPI module depends on `maven-api-core` and `maven-api-di`, allowing runtime environments like Maven 3 or Maven 4 to inject concrete implementations of `ProjectBuilder` and `ModelParser` without exposing implementation details to API consumers.

### Why are Maven API modules organized hierarchically?

The hierarchical organization enforces a strict dependency graph where foundational modules (annotations, XML, DI) have no dependencies, while higher-level modules sequentially build upon them. This structure, enforced by the module list in [`api/pom.xml`](https://github.com/apache/maven/blob/main/api/pom.xml) (lines 34-46), ensures that changes to low-level utilities propagate predictably and that consumers can depend on minimal artifact sets (e.g., just `maven-api-model`) without pulling in the entire API surface.

### Which Maven API module should I depend on for plugin development?

Plugin developers should typically depend on `maven-api-core` for access to `Project` and service interfaces, and `maven-api-plugin` for descriptor types like `PluginDescriptor`. If your plugin only needs to read the POM without full project resolution, depending solely on `maven-api-model` and `maven-api-xml` provides a lighter footprint while maintaining access to the immutable `Model` and `XmlNode` types.