Skip to content
Latchkey

jEnv vs SDKMAN: Managing Java Versions

jEnv switches between JDKs you have already installed; SDKMAN installs and manages JDKs plus other JVM tools.

jEnv is a thin version switcher: you install JDKs yourself (Homebrew, vendor packages), register them, and jEnv sets JAVA_HOME per project via a .java-version file. SDKMAN goes further, installing JDK distributions from many vendors and managing Gradle, Maven, Kotlin, and more from one catalog. jEnv is minimal and pairs with whatever installs JDKs; SDKMAN is an all-in-one installer and manager.

jEnvSDKMAN
Installs JDKsNo (you install)Yes
Sets JAVA_HOMEYes, per projectYes
Other JVM toolsNoGradle, Maven, Kotlin, etc.
Config file.java-versionNo standard file
Best forSwitching existing JDKsInstalling and managing all JVM tools

In CI

In CI, JDKs are usually provided by setup-java, making jEnv and SDKMAN more about local parity. jEnv suits developers who get JDKs from a package manager and just want per-project switching; SDKMAN suits teams that want one tool to install a specific vendor JDK plus build tools. Either keeps local and CI Java versions aligned.

Speed it up

Cache the JDK install and the build-tool caches keyed on your version pins and lockfiles. Both run on CI runners; faster managed runners shorten the JDK setup and build steps.

Decide with your own numbers, not a feature table

Feature comparisons age badly and rarely decide anything, because both tools in a mature category can do the job. What differs is how each behaves on your repository, and that takes one afternoon to measure.

Terminal
# time a cold install with each candidate, cache cleared
hyperfine --prepare "rm -rf node_modules" --warmup 1 \
  "<tool-a> install" "<tool-b> install"

# and the thing CI actually pays for: a cold run with no local cache
docker run --rm -v "$(pwd):/w" -w /w node:22 sh -c "<tool> install"

What actually changes when you switch

  • Lockfile format. A switch is a one-way door for anyone still on the old tool until everyone migrates, so plan it as a single coordinated change.
  • Resolution strictness. Tools differ on whether an undeclared transitive import works, and the stricter one will surface latent bugs as new failures.
  • CI cache configuration. The cache path and key differ per tool; carrying over the old ones silently disables caching.
  • Everyone on the team and every runner must move together. Pin the version so they cannot drift.

The verdict

Already installing JDKs another way and only needing per-project switching: jEnv. Wanting one tool to install JDK distributions and JVM build tools: SDKMAN. Many JVM developers use SDKMAN to install and jEnv-style switching only if they prefer a separate switcher.

Frequently asked questions

jEnv vs SDKMAN: Managing Java Versions?
jEnv is a thin version switcher: you install JDKs yourself (Homebrew, vendor packages), register them, and jEnv sets JAVA_HOME per project via a .java-version file. SDKMAN goes further, installing JDK distributions from many vendors and managing Gradle, Maven, Kotlin, and more from one catalog.
In CI?
In CI, JDKs are usually provided by setup-java, making jEnv and SDKMAN more about local parity. jEnv suits developers who get JDKs from a package manager and just want per-project switching; SDKMAN suits teams that want one tool to install a specific vendor JDK plus build tools. Either keeps local and CI Java versions aligned.
Speed it up?
Cache the JDK install and the build-tool caches keyed on your version pins and lockfiles. Both run on CI runners; faster managed runners shorten the JDK setup and build steps.
Which should I choose?
Already installing JDKs another way and only needing per-project switching: jEnv. Wanting one tool to install JDK distributions and JVM build tools: SDKMAN. Many JVM developers use SDKMAN to install and jEnv-style switching only if they prefer a separate switcher.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card