This project aims at providing faster Maven builds using techniques known from Gradle and Takari.
Architecture overview:
-
mvndembeds Maven (so there is no need to install Maven separately). -
The actual builds happen inside a long living background process, a.k.a. daemon.
-
One daemon instance can serve multiple consecutive requests from the
mvndclient. -
The
mvndclient is a native executable built using GraalVM. It starts faster and uses less memory compared to starting a traditional JVM. -
Multiple daemons can be spawned in parallel if there is no idle daemon to serve a build request.
This architecture brings the following advantages:
-
The JVM for running the actual builds does not need to get started anew for each build.
-
The classloaders holding classes of Maven plugins are cached over multiple builds. The plugin jars are thus read and parsed just once. SNAPSHOT versions of Maven plugins are not cached.
-
The native code produced by the Just-In-Time (JIT) compiler inside the JVM is kept too. Compared to stock Maven, less time is spent by the JIT compilation. During the repeated builds the JIT-optimized code is available immediately. This applies not only to the code coming from Maven plugins and Maven Core, but also to all code coming from the JDK itself.
mvnd brings the following features on top of the stock Maven:
-
By default,
mvndis building your modules in parallel using multiple CPU cores. The number of utilized cores is given by the formulaMath.max(Runtime.getRuntime().availableProcessors() - 1, 1). If your source tree does not support parallel builds, pass-T1into the command line to make your build serial. -
Improved console output: we believe that the output of a parallel build on stock Maven is hard to follow. Therefore, we implemented a simplified non-rolling view showing the status of each build thread on a separate line. This is what it looks like on a machine with 24 cores:
Once the build is finished, the complete Maven output is forwarded to the console.
Install using SDKMAN!
If SDKMAN! supports your operating system, it is as easy as
sdk install mvndIf you used the manual install in the past, please make sure that the settings in ~/.m2/mvnd.properties still make
sense. With SDKMAN!, the ~/.m2/mvnd.properties file is typically not needed at all, because both JAVA_HOME and
MVND_HOME are managed by SDKMAN!.
Install using Homebrew
brew install mvndaemon/homebrew-mvnd/mvndNote: There are two formulae: mvnd installs the preview 2.x version (embedding Maven 4.0.x), and mvnd@1 installs the stable 1.x version (embedding Maven 3.9.x).
Install using MacPorts
sudo port install mvndInstall using aqua
aqua g -i apache/maven-mvndWe’re looking for contribution to support Chocolatey, Scoop or asdf. If you fancy helping us…
Optionally, you can set up completion as follows:
# ensure that MVND_HOME points to your mvnd distribution, note that sdkman does it for you
$ echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.bashrcbash is the only shell supported at this time.
-
Download the latest ZIP suitable for your platform from https://downloads.apache.org/maven/mvnd/
-
Unzip to a directory of your choice
-
Add the
bindirectory toPATH -
Optionally, you can create
~/.m2/mvnd.propertiesand set thejava.homeproperty in case you do not want to bother with setting theJAVA_HOMEenvironment variable. -
Test whether
mvndworks:$ mvnd --version Maven Daemon 0.0.11-linux-amd64 (native) Terminal: org.jline.terminal.impl.PosixSysTerminal with pty org.jline.terminal.impl.jansi.osx.OsXNativePty Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /home/ppalaga/orgs/mvnd/mvnd/daemon/target/maven-distro Java version: 11.0.1, vendor: AdoptOpenJDK, runtime: /home/data/jvm/adopt-openjdk/jdk-11.0.1+13 Default locale: en_IE, platform encoding: UTF-8 OS name: "linux", version: "5.6.13-200.fc31.x86_64", arch: "amd64", family: "unix"
If you are on macOS, you’ll need to remove the quarantine flags from all the files after unpacking the archive:
$ xattr -r -d com.apple.quarantine mvnd-x.y.z-darwin-amd64
The daemon runs on Java 17 or later.
The bin/mvnd native client is built with GraalVM native-image for four platforms; on any other platform,
bin/mvnd.sh (bin/mvnd.cmd on Windows) runs the Java client instead.
The daemon also loads mvndnative, a small JNI library for setenv, chdir and macOS memory information,
which is prebuilt for the platforms in the following table.
The last column lists the Java 17 or later builds that vendors published as of October 2026.
| Platform | Native client | JNI library | Java builds (17, 21, 25) |
|---|---|---|---|
Linux x86_64 |
yes |
yes |
Temurin, Liberica, Zulu, Microsoft: 17, 21, 25 |
Linux aarch64 |
yes |
yes |
Temurin, Liberica, Zulu, Microsoft: 17, 21, 25 |
Linux ppc64le |
no |
yes |
Temurin, Liberica: 17, 21, 25 |
Linux armv6, armv7 (hard-float) |
no |
yes |
Liberica: 17, 21, 25; Temurin, Zulu: 17 |
Linux arm ( |
no |
yes |
none found |
Linux x86 (32-bit) |
no |
yes |
Liberica: 17, 21; Zulu: 17 |
macOS aarch64 |
yes |
yes |
Temurin, Liberica, Zulu, Microsoft: 17, 21, 25 |
macOS x86_64 |
no |
yes |
Temurin, Liberica, Zulu, Microsoft: 17, 21, 25 |
Windows x86_64 |
yes |
yes |
Temurin, Liberica, Zulu, Microsoft: 17, 21, 25 |
Windows x86 (32-bit) |
no |
yes |
Temurin, Zulu: 17 |
Windows aarch64 |
no |
no |
Microsoft, Zulu: 17, 21, 25; Temurin: 21 |
FreeBSD x86_64 |
no |
yes |
FreeBSD ports: 17, 21, 25 |
FreeBSD x86 (32-bit) |
no |
yes |
FreeBSD ports: 17, 21 |
On Linux, the native client links to the system C library dynamically and needs glibc 2.12 or later on x86_64,
or glibc 2.17 or later on aarch64; the release workflow checks both limits.
When the native client cannot load, for example on an older glibc, bin/mvnd.sh runs the Java client instead.
A native client takes its glibc requirement from the system that builds it, not from GraalVM:
GraalVM’s own static libraries need nothing newer than glibc 2.17.
Built on Ubuntu 24.04 without the release workflow’s adjustments, the client needs glibc 2.34; built inside AlmaLinux 8,
it needs only glibc 2.17 on aarch64. AlmaLinux 8 needs the zlib-static package from its powertools repository for
the build.
mvnd is designed to accept the same command line options like stock mvn (plus some extras - see below), e.g.:
mvnd verify--status lists running daemons
--stop kills all running daemons
mvnd --help prints the complete list of options
Configuration can be provided through the properties file. Mvnd reads the properties file from the following locations:
-
the properties path supplied using
MVND_PROPERTIES_PATHenvironment variable ormvnd.propertiesPathsystem variable -
the local properties path located at
[PROJECT_HOME]/.mvn/mvnd.properties -
the user properties path located at:
[USER_HOME]/.m2/mvnd.properties -
the system properties path located at:
[MVND_HOME]/conf/mvnd.properties
Properties defined in the first files will take precedence over properties specified in a lower ranked file.
A few special properties do not follow the above mechanism:
-
mvnd.daemonStorage: this property defines the location where mvnd stores its files (registry and daemon logs). This property can only be defined as a system property on the command line -
mvnd.id: this property is used internally to identify the daemon being created -
mvnd.extClasspath: internal option to specify the maven extension classpath -
mvnd.coreExtensionFilePath: internal option to specify the maven extension configuration file path
For a full list of available properties please see /dist/src/main/distro/conf/mvnd.properties.
-
git -
Maven
-
Download and unpack GraalVM CE from GitHub
-
Set
JAVA_HOMEto where you unpacked GraalVM in the previous step. Check thatjava -versionoutput is as expected:$ $JAVA_HOME/bin/java -version openjdk version "11.0.9" 2020-10-20 OpenJDK Runtime Environment GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06) OpenJDK 64-Bit Server VM GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06, mixed mode, sharing)
-
Install the
native-imagetool:$ $JAVA_HOME/bin/gu install native-image -
native-imagemay require additional software to be installed depending on your platform - see thenative-imagedocumentation.
$ git clone https://github.com/apache/maven-mvnd.git
$ cd maven-mvnd
$ mvn clean verify -Pnative
...
$ cd client
$ file target/mvnd
target/mvnd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=93a554f3807550a13c986d2af9a311ef299bdc5a, for GNU/Linux 3.2.0, with debug_info, not stripped
$ ls -lh target/mvnd
-rwxrwxr-x. 1 ppalaga ppalaga 25M Jun 2 13:23 target/mvndPlease note that if you are using Windows as your operating system you will need the following prerequisites for building maven-mvnd:
a version of Visual Studio with the workload "Desktop development with C++" and the individual component "Windows Universal CRT SDK".
$ cp -R dist/target/mvnd-[version] [target-dir]Then you can simply add [target-dir]/bin to your PATH and run mvnd.
We’re happy to improve mvnd, so feedback is most welcome!
