Native Maven is experimental and very early in development. Expect gaps, rough edges, and changes to flags and behavior between releases. Keep a regular Maven installation available for builds that must not break.
Native Maven is Apache Maven 4 compiled to a native executable with GraalVM
Native Image. It starts in milliseconds instead of seconds and can run typical
pom.xml builds about twice as fast as Maven on a JVM. Elide drives it
through the elide mvn command, so no separate Maven or JDK installation is
needed.
Run a build
Everything after -- is passed to Maven unchanged:
elide mvn -- package
elide mvn -- -f app/pom.xml clean install
elide mvn -- --versionThe multi-module project root is located the same way Maven’s launcher does
it: from the -f/--file directory (or the working directory), walking up
to the nearest .mvn marker.
First run
The Elide distribution ships no Native Maven images, which keeps the download
small. On first use, elide mvn asks to download the image it needs:
Native Maven component 'generic' is not installed. Download it now? [Y/n]Answer yes once. Images install under lib/maven/bin/ inside the Elide home
directory and are reused on every later run. Non-interactive sessions, such
as CI, approve the download automatically.
Pass --yes after -- to approve every download without a prompt, even when
a terminal is attached. This suits CI runners that allocate a TTY, and any
script that must not block on input:
elide mvn -- --yes packagePublished images exist for these platforms:
| Platform | Architecture |
|---|---|
| Linux | x86_64, aarch64 |
| macOS | aarch64 |
| Windows | x86_64 |
Flavors
A native image cannot load arbitrary classes at run time, so a set of Maven plugins is compiled into each image. That set is called a flavor. Plugins inside the flavor run at native speed; anything else depends on the mode below.
| Flavor | Baked plugins | Best for |
|---|---|---|
generic | Maven’s default lifecycle: clean, resources, compiler, surefire, jar, install, deploy | Plain Java or Kotlin projects with no build plugins |
spring@4.1.0 | Everything a Spring Initializr project on Spring Boot 4.1 uses | Spring Boot 4.1.x |
spring@4.0.7 | Same, for Spring Boot 4.0 | Spring Boot 4.0.x |
Elide selects the flavor automatically. It reads the project’s pom.xml for a
Spring Boot version, taken from a spring-boot-starter-parent parent or an
explicit spring-boot-maven-plugin version, and picks the published image on
the same major.minor line. A Boot 4.1.3 project therefore uses
spring@4.1.0. Projects without a detectable Boot version use generic.
Version placeholders such as ${spring.version} are not resolved and fall
back to generic. Request a flavor explicitly when detection does not match
your project:
elide mvn -- --flavor spring@4.1.0 package
elide mvn -- --flavor=spring@4.0.7 -f app/pom.xml install--flavor is an Elide option and is removed before the arguments reach
Maven. It may appear anywhere after --. Each flavor is a separate download
that installs on first use, the same way as the generic image.
Modes
Mode decides what happens when a build needs a plugin that is not baked into
the selected flavor. Set it with --mode=<value> after --:
elide mvn -- --mode=mixed package| Mode | Behavior |
|---|---|
native (default) | Only baked plugins run. A missing plugin fails the build early with an error that names the flavor most likely to contain it and suggests --mode=mixed. Fastest start and run. |
mixed | Baked plugins run natively. Every other goal runs, one at a time, on a HotSpot JVM booted inside the same process. The best balance of speed and compatibility. |
legacy | The whole build runs on the in-process HotSpot JVM as plain Apache Maven. No speedup; useful as a baseline to compare the other modes against. |
Only the --mode=value form is recognized. The -Dnmvn.mode=<value> system
property works too; an explicit flag wins over it.
mixed and legacy need a Maven distribution to boot the JVM from. On first
use of either mode, elide mvn asks to download it into lib/maven/ next to
the images. This is Native Maven’s own distribution, which carries the
in-process bridge that stock Apache Maven lacks. Elide itself serves as the
JVM; no separate JDK is required.
Mixed mode limits
Each delegated goal is a fresh Maven invocation inside the shared JVM, which adds roughly 0.2 seconds per goal after a one-time boot. A build that delegates most of its goals still works but no longer runs at native speed; pick a closer flavor instead.
Artifacts produced by a delegated goal are not attached to the native
session. If the packaging plugin is not baked, run package rather than
install or deploy, because the baked install goal cannot see a jar that a
delegated jar:jar wrote. Plugin configuration given on the command line
crosses the boundary only as -D user properties.
Compilation
Native Maven images include the Java compiler and compile in-process. A
plugin configured to fork the compiler resolves javac from the Elide
installation, so forked builds work without any other JDK on the machine.
Output
In an interactive terminal, elide mvn shows a live status line with the
running plugin, goal, version, and module, then prints a summary of completed
phases and the total build time. On failure it prints the full Maven log.
Pass --porcelain after -- to stream Maven’s own output instead. Verbose
and debug runs, and non-interactive sessions, stream it automatically:
elide mvn -- --porcelain packageInspect an installed image
Each image can describe itself. Run the binary directly from the Elide home
directory, with --info as its first argument:
<elide-home>/lib/maven/bin/nmvn-generic --info
<elide-home>/lib/maven/bin/nmvn-spring-4.1.0 --info=plugins--info prints the flavor, the variant, and every baked plugin. Passing
--info=plugins, --info=flavor, or --info=variant prints just that value,
which suits scripts.
Compatibility
Native Maven aims to become a drop-in replacement. It reads the same
pom.xml, runs the same plugins, and follows the same lifecycle as Apache
Maven 4, but plugin coverage is still limited to the published flavors and
compatibility is not yet complete. --flavor and --mode are opt-ins layered
on top and are meant to stay usable across future releases.
Related
- Maven Dependencies installs Maven coordinates
declared in
elide.pklwithout running a Maven build. - Dependencies covers install flags and the on-disk layout.
- JVM Toolchain lists the compiler, formatter, and packaging commands.