The last version manager you'll ever need

programming languages by AAMINE1965, licensed under CC BY-SA 4.0

Chances are high you have already used tfenv, pyenv, SDKMAN!, rbenv, nvm or some other version manager. In case you haven't: A version manager is a program that let's you install multiple versions of a tool for different contexts: Your one project needs version X, the other version Y.alpha. Just the tool in one version all the time does not cut it as different versions behave differently. So if people work on the same project with different versions of core tools, it often gets messy:

  • At work you get a build error on a project that "just works" on some coworkers machine.

  • As an open source project maintainer, you get support requests from people who run into problems because of version conflicts in tooling.

  • The build fails locally because your python version was automatically updated by your package manager.

  • You updated the build tool locally, because you want that new feature it provides, and now you have to update the build pipeline separately.

And even with personal projects like this blog version management comes in handy: Because if I try to write a blog post on a new machine, I always scratch my head and ask myself: Which version of hugo am I using again?

Documentation to the rescue?

Many projects I have seen try to solve this problem with documentation. This does not work too well in my experience. First because it is seldom read, second because it needs to be updated regularly (which often does not happen) and third because it leaves every user to cook up his own solution on how to use all the needed tools versioned appropriately in the context of the project: Installing them and figuring out how to deal with possible version conflicts on their machine.

Photo by Tim Wildsmith under the Unsplash License

Version managers

The list of tools which have a dedicated version manager is long: Ruby, Python, Java and Go to name a few programming languages. kubectl, node, maven and terraform as some popular tools which sport their own version manager. All of them solve the problem described. But obviously they come at a cost: One has to install them, learn how to use them and integrate them into the build pipeline. This investment accrues for every new tool and so it is done at most for the most central ones.

All of those version managers do the same few things:

  1. Provide you with a list of versions.

  2. Conveniently install them.

  3. Manipulate your PATH so you use the right version in the right context.

Sure, there is variation on how releases are made available and installed, but a good part of what different version managers do is the same. So it makes quite a lot of sense to have ONE version manager that is extendable for different tools.

One version manager to rule them all

asdf is an extendable version manager. At the time of writing it supports 453 different tools via plugins. By the time you read this, it likely supports more. After installation you can look that up easily by executing:

asdf plugin list all | wc -l

So asdf has plugins: One for each tool it supports. It is highly likely that the tools you need are part of that list. If one of them is not: asdf is an extendable version manager. So writing a new plugin is easy if you know a bit of Bash. I have written a few, because they are fun and quick to write.

asdf works on Linux and MacOS and thanks to WSL also on Windows. There is support for Github Actions. The list of plugins is so long it became a standard way for me to install tools globally on multiple machines (which comes in especially handy as I also need to use a Mac for work now).

Introducing asdf to your project makes adding additional programming languages, linters, formatters and other utilities to your projects quite cheap. You can even automate the installation of new versions by using direnv alongside it. It is compatible with some of the more popular single purpose version managers mentioned before to make the transition easier.

asdf is a simple and small tool. It follows the Unix philosophy of doing one thing well.

I'll end this with the ballad of asdf. Yes, it even has that:

Once upon a time there was a programming language There were many versions of it So people wrote a version manager for it To switch between versions for projects Different, old, new.

Then there came more programming languages So there came more version managers And many commands for them

I installed a lot of them I learnt a lot of commands

Then I said, just one more version manager Which I will write instead

So, there came another version manager asdf version manager -

A version manager so extendable for which anyone can create a plugin To support their favourite language No more installing more version managers Or learning more commands

linux  bash  macos 

See also