Mise vs SDKMAN: Why I'm Switching After Years of .sdkmanrc

A colleague mentioned Mise today. I’ve been a loyal SDKMAN user for years — .sdkmanrc in every project, sdk use java 21.0.2-tem committed to muscle memory. It works, it’s reliable, I’ve never had a reason to look elsewhere.
Then I actually looked at what Mise does, and I’m not sure I can go back.
The Problem with One Tool per Language
SDKMAN manages JDKs (and Gradle, Maven, and a few other JVM tools). It does that well. But my projects don’t just need Java:
- Java 21 (Temurin)
- Node 22 (for the frontend build)
- Terraform (for infrastructure)
- Python 3.12 (for scripts)
So I have SDKMAN for Java, nvm for Node, pyenv for Python, and tfenv for Terraform. Each has its own config file, its own shell hooks, its own way of pinning versions. My .zshrc loads four version managers, each adding latency to every new shell.
Mise replaces all of them with one tool and one config file:
# .mise.toml
[tools]
java = "temurin-21"
node = "22"
python = "3.12"
terraform = "1.9"That’s it. One file in the repo root. Everyone on the team gets the same versions. No “works on my machine” because someone forgot to run sdk install.
What Mise Does Better
Speed
SDKMAN uses shell scripts. Every new terminal loads SDKMAN’s init script, which adds noticeable latency. Mise is written in Rust and modifies PATH directly instead of using shims. The overhead is ~5ms on shell startup vs. ~120ms for shim-based tools like asdf. SDKMAN falls somewhere in between, but it’s not in Mise’s league.
One Config for Everything
Instead of .sdkmanrc + .nvmrc + .python-version + .terraform-version, you have a single .mise.toml. It supports all 500+ tools from the asdf plugin ecosystem, plus its own curated backends.
Environment Variables
Mise doubles as a direnv replacement. You can set project-specific environment variables in the same config:
[tools]
java = "temurin-21"
[env]
SPRING_PROFILES_ACTIVE = "local"
DATABASE_URL = "jdbc:postgresql://localhost:5432/myapp"No more .env files that accidentally get committed.
Tasks
Mise can also replace make and npm scripts:
[tasks.dev]
run = "java -jar build/libs/app.jar"
depends = ["build"]
[tasks.build]
run = "./gradlew build -x test"mise run dev # builds first, then runsIs this necessary? No. But it’s nice to have project tasks defined alongside tool versions in one place.
The Migration Path
Here’s the part that convinced me: Mise reads .sdkmanrc natively. It maps SDKMAN’s vendor strings to its own format — 21.0.2-tem becomes temurin-21.0.2. Your existing .sdkmanrc files just work.
The migration is gradual:
- Install Mise:
curl https://mise.run | sh - Add to your shell:
eval "$(mise activate zsh)" - Your existing
.sdkmanrcfiles are picked up automatically - When you’re ready, convert to
.mise.tomlfor the full feature set
You don’t have to uninstall SDKMAN immediately. Both can coexist while you transition.
What SDKMAN Still Does Better
Fair is fair:
- JVM ecosystem breadth — SDKMAN supports more JDK distributions (GraalVM, Liberica NIK, Bisheng) that Mise doesn’t have yet
- JVM-specific tooling — SDKMAN manages Gradle, Maven, Micronaut CLI, Quarkus CLI, and other JVM tools natively. With Mise, some of these require asdf plugins
- Community — SDKMAN has years of JVM community trust and a larger user base in the Java world
- Candidates —
sdk list javawith its table of available distributions is a great discovery experience
If your world is purely JVM and you never touch Node/Python/Terraform, SDKMAN is still excellent. The case for Mise strengthens as your toolchain diversifies.
The Comparison
| SDKMAN | Mise | |
|---|---|---|
| Languages | JVM ecosystem | 500+ tools (Java, Node, Python, Go, Rust, Terraform…) |
| Config file | .sdkmanrc | .mise.toml (also reads .sdkmanrc) |
| Shell startup | ~50-100ms | ~5ms |
| Env vars | No | Yes (replaces direnv) |
| Tasks | No | Yes (replaces make) |
| Written in | Bash | Rust |
| JDK distributions | Extensive | Good (missing GraalVM, Liberica NIK) |
| Windows | Via Git Bash/WSL | Native (for non-asdf backends) |
Bottom Line
SDKMAN solved a real problem and solved it well. I’ve used it for years without complaints. But Mise is what SDKMAN would look like if you designed it today — polyglot, fast, and aware that modern projects use more than one language.
If your .zshrc loads three version managers, Mise is a straightforward upgrade. If you’re happy with SDKMAN and only write Java — keep it. There’s no reason to switch for the sake of switching.
But if a colleague mentions Mise, try it. I did, and my shell is 200ms faster and my project root has one config file instead of four.


