$ cd my-service
$ jolta pin 21 # writes .java-version
$ java -version # → OpenJDK 21, automatically
$ cd ../legacy-app # has .java-version with "8"
$ java -version # → 1.8 — no sdk use, no jenv shell, no export JAVA_HOME
Install
Prebuilt binaries for every platform — no Rust toolchain, no runtime, nothing to compile.
macOS Apple Silicon & Intel
Homebrew:
brew install OneAppPlatform/tap/jolta
jolta setup
Or the one-line installer:
curl -fsSL https://raw.githubusercontent.com/OneAppPlatform/jolta/main/install.sh | sh
Linux x86_64 & arm64 · static musl, any distro
One-line installer:
curl -fsSL https://raw.githubusercontent.com/OneAppPlatform/jolta/main/install.sh | sh
Or Homebrew on Linux:
brew install OneAppPlatform/tap/jolta
jolta setup
Windows x86_64
Download jolta-x86_64-pc-windows-msvc.zip from the
releases page, unzip, then:
.\jolta.exe setup
Follow the two printed steps: add the shims directory to your user
PATH, and add the PowerShell hook line to your $PROFILE.
Verify with a new shell:
jolta doctor
How it works
Jolta puts lightweight shims on your PATH
(java, javac, jar, jshell, …) — each one a
link to the single jolta binary. Every invocation walks up from the current directory to
the nearest .java-version, resolves an installed JDK for it, sets
JAVA_HOME, and execs the real tool. Resolution takes ~2 ms, invisible
next to JVM startup.
If a project pins a version you don't have, the first invocation
downloads it on demand (Volta-style) from the distro's official endpoint —
never triggered by merely cd-ing around, safe under parallel builds, and
disabled with JOLTA_NO_AUTO_INSTALL=1. Restricted networks can set
JOLTA_DOWNLOAD_BASE to serve JDKs from an internal mirror
({base}/{vendor}/{version}/{os}-{arch}.{ext}) instead of the vendor
endpoints.
Jolta also finds the JDKs you already have: Homebrew,
/Library/Java/JavaVirtualMachines, SDKMAN, /usr/lib/jvm,
Windows Program Files, and JAVA_HOME_<major>_* environment
variables.
Pinning
The pin is a plain .java-version file (compatible with jenv and asdf) —
commit it to your repo:
jolta pin 21 # this project uses Java 21
jolta default 21 # global fallback when a project has no pin
Resolution order: JOLTA_JAVA_VERSION env var → nearest
.java-version walking up → jolta default → system default JDK.
On a machine with no JDK at all, the first java run installs the latest
LTS (Temurin) and sets it as your default.
A major pin (21) matches the highest installed build of that major.
An exact pin (21.0.2) means exact — never silently substituted, and
auto-installed precisely. .sdkmanrc files (java=21.0.2-tem)
are honored with vendor mapping when no .java-version claims the
directory. jolta catalog (alias search) shows what every distro
publishes — latest per distro, per-major comparisons, and @v prefix
filters like temurin@21.0 — with installed versions marked.
Distros
A spec can name a JDK distribution as distro@version or
distro-version:
jolta pin corretto@21 # this project wants Amazon Corretto 21
jolta install graalvm@25 # explicitly fetch a GraalVM JDK
- Downloadable:
temurin(default),corretto,graalvm,oracle,zulu. - Recognized when matching: those five plus
openjdk(Homebrew builds). - A distro-qualified pin is strict —
corretto-21picks an installed Corretto 21 over a Homebrew OpenJDK 21, and auto-installs Corretto if missing. A bare21matches any distro.
Point releases: jolta update checks jolta-managed JDKs against the
vendors (via redirect filenames — no downloads) and jolta upgrade
fetches newer builds and prunes superseded ones. Homebrew/system JDKs stay with
their own package managers; resolution picks the highest build of a major, so
their upgrades apply automatically.
JAVA_HOME, Maven & Gradle
Two mechanisms keep JAVA_HOME correct:
- Shims export it for everything they exec.
- The shell hook (installed by setup; zsh, bash, and PowerShell)
re-resolves it every time you change directory — covering tools that read
JAVA_HOMEdirectly, like Maven, Gradle, and IDEs launched from a terminal. If a pin can't be satisfied the hook unsetsJAVA_HOME, so builds fail loudly rather than silently using the wrong JDK.
Don't export JAVA_HOME manually in your profile — the hook owns it. In
scripts and CI, use jolta exec mvn ... or
eval "$(jolta env)". jolta doctor flags stale values.
Commands
| Command | What it does |
|---|---|
jolta setup | Install shims + shell profile setup |
jolta pin <spec> | Write .java-version in the current directory |
jolta default <spec> | Set the global fallback version |
jolta install <spec> | Download a JDK (21, corretto@21, graalvm@25) |
jolta catalog [x] | The JDK catalog: latest per distro/major, @v prefix filters (alias search) |
jolta update | Check jolta-managed JDKs for newer point releases |
jolta upgrade [spec] | Upgrade jolta-managed JDKs, pruning old builds |
jolta uninstall <name> | Remove a jolta-managed JDK |
jolta list | List visible JDKs with distro, star the active one |
jolta jdks | Machine-readable list: major / version / distro / home |
jolta current | Show the version resolved here, and why |
jolta which [tool] | Full path the shim would exec |
jolta exec <cmd> | Run any command with JAVA_HOME/PATH set |
jolta env | Print export lines for eval |
jolta home | Print the resolved JAVA_HOME |
jolta hook [shell] | Print the cd hook (zsh, bash, powershell) |
jolta reshim | Regenerate shims after installing JDKs elsewhere |
jolta doctor | Diagnose PATH / shim / JAVA_HOME problems |
jolta implode | Uninstall jolta completely |
How jolta compares
An honest table, current as of July 2026 — corrections welcome.
| jolta | mise | SDKMAN | jenv | asdf | |
|---|---|---|---|---|---|
.java-version honored by default |
✓ | opt-in | ✗ | ✓ | opt-in |
.sdkmanrc honored |
✓ | opt-in | opt-in | ✗ | ✗ |
JAVA_HOME set automatically |
✓ | opt-in | ✓ | plugin | plugin |
| Downloads JDKs | ✓ | ✓ | ✓ | ✗ | ✓ |
Auto-install on first java run |
✓ | partial | ✗ | ✗ | ✗ |
| Exact point-release pinning | ✓ | ✓ | ✓ | partial | ✓ |
| GraalVM | ✓ | ✗ | ✓ | manual | ✓ |
| Finds JDKs you already have (brew, system) | ✓ | ✗ | ✗ | manual | ✗ |
| Point-release upgrades with cleanup | ✓ | ✓ | ✓ | ✗ | manual |
| Remote catalog browsing | ✓ | ✓ | ✓ | ✗ | ✓ |
| Native Windows | ✓ | ✓ | WSL | ✗ | ✗ |
| Corporate mirror support | ✓ | partial | ✗ | ✗ | partial |
| Also manages Maven/Gradle/other tools | ✗ | ✓ | ✓ | ✗ | ✓ |
| Zero config files of its own | ✓ | ✗ | ✗ | ✓ | ✗ |
| Battle-tested since | 2026 | 2023 | 2012 | 2011 | 2014 |
Fair summary: if Java is one of five languages you juggle, mise is
excellent. If Java is the job, jolta does the whole job by default — nothing to
enable, nothing to configure, and a .java-version is all your repo
needs.
Uninstall
jolta implode
Removes ~/.jolta and the jolta lines from your shell profile, after a
confirmation prompt that lists exactly which jolta-installed JDKs will be deleted.
JDKs installed outside jolta and your .java-version files are never touched —
jolta only ever deletes what it downloaded itself.