asdf. A Developer's Best Friend

This post won’t be a particularly long one, I just want to introduce you all to the greatest not-super-popular (yet) tool on the planet. It’s called asdf and it’s an open source tool for version management of other tools. asdf is available on GitHub and to put it shortly, it allows you to have multiple versions of a single tool installed on your machine at the same time, using only the one you specifically want for any particular project. Let me run you through an example, and the reason I initially got asdf. Ruby.

When I first started with Ruby, I needed to install it. In their wisdom, my new coworkers at the time encouraged me to install Ruby through a version manager rather than having a base install for my operating system. Installing Ruby through asdf means that for any particular project, I do following:

cd ~/repos/my-new-project

asdf local ruby 2.5.0

It pretty much does what it sounds like it does. I’m telling asdf that for this local directory (which includes children directories if you need), I want to use Ruby, and use version 2.5.0 of Ruby. Easy enough right? It’s particularly powerful when I have multiple versions of Ruby installed through asdf. Say I want to upgrade my project to a newer version of Ruby but I want to check to see if it’ll work. All I have to do is run asdf local ruby 2.5.3 and from there on out, when I run ruby on the command line, it will reference Ruby 2.5.3. That’s pretty standard usage for Ruby version managers, but what else can asdf do?

(It’s worth noting for Ruby specifically since there is also rvm and rbenv, you can tell asdf to use ‘legacy version files’, at which point it will use, respect, and write to, a .ruby-version file.)

The beauty of asdf is that it can version manage all of your tools at once. Do some Ruby projects but also do some .NET Core projects but also use the Node runtime sometimes? No problem, asdf can manage all of those for you. Say you’re starting a new project and implementing it with a .NET Core back end, React front end, and Postgres for your database. asdf’s got you.

asdf local nodejs 10.2.0

asdf local dotnet-core 2.2.100

asdf local postgres 11.1

but how expansive is the reach of asdf? Since support for languages and frameworks is achieved through the creation of open source plugins, the list is pretty long. See below.

What can it manage?

Here’s the beauty of asdf. At time of writing, here are all the languages/frameworks/tools that asdf can version-manage (directly off their page)

Who needs this tool


That was easy!

How to install it

If you’re on a macOS machine, you can feel free to follow the standard installation, but you can also follow the simpler: brew install asdf

For everyone else, asdf does a great job of documentation and has a thorough README on their repository. Give it a read and follow the directions. I would highly recommend removing any current versions of tools that you intend to manage with asdf that you currently have installed directly on the operating system somewhere. asdf should be able to handle it if you don’t, but better safe than sorry.

Since asdf does a lot with mutating shell commands, be wary that you should probably restart your shell after you install

How to use it

I like to break asdf up into a few layers in my head. The first layer is plugins. These are the languages that your local instance of asdf supports version-controlling. Things like Ruby or .NET Core. In order to version control Ruby or .NET Core, you need to install the appropriate plugin. Luckily, installing plugins is super easy.

# Show all available plugins (the list above)
asdf plugin-list-all

# Install a plugin
asdf plugin-add dotnet-core
# or
asdf plugin-add ruby

The next layer down is versions. This is where you install particular versions of that plugin/tool. It looks like this:

# Show all available versions for a particular plugin
asdf list-all ruby
etc.. (to current)

asdf list-all dotnet-core

# Install a particular version(s)
asdf install ruby 2.5.0
# or
asdf install ruby 2.5.3
# or
asdf install dotnet-core 2.2.100

Finally, the last layer is bindings, although that name comes exclusively from me and is not in their documentation. It’s at this layer where you tell asdf which tool and version to use in a particular project directory.

# List current bindings for directory
asdf current
nodejs         10.16.3  (set by /Users/somebody/repos/proj-name/.tool-versions)
ruby           No version set for ruby; please run `asdf <global | local> ruby <version>`

# Bind up some tools/versions
asdf local ruby 2.5.0
# and/or
asdf local node 10.2.0

That’s all there is to it! Enjoy your modular and extensible multi-tool version management!

Other things

asdf does support global defaults for the plugins you have installed. If you set those, they will manifest into a .tool-versions file at your $HOME directory. I do not recommend setting global defaults. It can lead to confusion later. Be intentional about the tools and versions you use 😊

Join the Conversation

Latest Blog Posts