Today I was reminded again of the tool asdf which can manage multiple runtime versions with a single CLI tool. I have been a long-time user of Sdkman for managing my JVM related tool chain (JDK, Kotlin, Gradle, etc), but then I use Homebrew for managing Nodejs, Python, Poetry.

I don’t like that this approach as it is not cross-platform (by which I mean Linux and MacOS), and uses a combination of tools - asdf and homebrew.

So I have decided to try out asdf in anger. It’s quite easy to get started following the documentation, but the main things to annoy me are:

  • By default it does not respect existing files like .nvmrc when picking a version of a tool. You need to add legacy_version_file = yes to the file ~.asdfrc to enable this behaviour.

  • When installing a new tool, it does not immediately register it as the global default. For example, installing gradle requires two commands: asdf install gradle latest and asdf global gradle latest.

  • It does not handle JDK distributions as well as sdkman, which is hardly a surprise. The support for upgrading multiple versions (11 and 17) is clunky.

So I have written the following script that works around these limitations, and can be used to boostrap and update my asdf installation. Sharing in case it’s useful for others.

#!/usr/bin/env zsh
# Updates my asdf install. Very basic for now.
# Fail quickly
set -e

# Ensure sensible configuration file
echo Checking $rcfile...
test -f $rcfile || touch $rcfile
if [[ $(grep -c legacy_version_file $rcfile) = 0 ]]; then
    echo ...adding 'legacy_version_file = yes'
    echo 'legacy_version_file = yes' >> $rcfile

# Update installed plugins
echo Updating installed plugins...
asdf plugin-update --all > /dev/null

# Ensure all the plugins are installed
echo Checking plugins are installed...
for n in java kotlin gradle python poetry nodejs; do
    if asdf plugin-list | grep -cq $n; then
        true # Already installed
        echo ...installing $n
        echo asdf plugin-add $n

echo Updating versions...
# Special Java logic
asdf install java latest:temurin-11
asdf install java latest:corretto-17
asdf global java latest:corretto-17

# Special Nodejs logic
asdf install nodejs lts
asdf global nodejs lts

# The nice ones
for n in gradle kotlin python poetry; do
    asdf install $n latest
    asdf global $n latest

echo ...done
echo -------------
echo 'Need to run `asdf uninstall <tool> <old-version>` as necessary'