JonSullivanDev

A Collection of Thoughts

asdf. A Developer's Best Friend

20 January 2019

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):

Language Repository CI Status
adr-tools td7x/asdf/adr-tools pipeline status
Bazel mrinalwadhwa/asdf-bazel Build Status
Brig Ibotta/asdf-brig Build Status
Clojure halcyon/asdf-clojure Build Status
CMake srivathsanmurali/asdf-cmake Build Status
Conduit gmcabrita/asdf-conduit Build Status
Consul Banno/asdf-hashicorp Build Status
Coq gingerhot/asdf-coq Build Status
Crystal marciogm/asdf-crystal Build Status
D (DMD) sylph01/asdf-dmd Build Status
Dep paxosglobal/asdf-dep Build Status
Desk endorama/asdf-desk Build Status
docker-slim everpeace/asdf-docker-slim Build Status
Elasticsearch mikestephens/asdf-elasticsearch Build Status
Elixir asdf-vm/asdf-elixir Build Status
Elm vic/asdf-elm Build Status
Erlang asdf-vm/asdf-erlang Build Status
Go kennyp/asdf-golang Build Status
GoHugo mgladdish/asdf-gohugo  
GraalVM vic/asdf-graalvm Build Status
Gradle rfrancis/asdf-gradle Build Status
Haskell vic/asdf-haskell Build Status
Helm Antiarchitect/asdf-helm Build Status
Helmfile feniix/asdf-helmfile Build Status
heptio-authenticator-aws neerfri/asdf-heptio-authenticator-aws Build Status
Idris vic/asdf-idris Build Status
ImageMagick mangalakader/asdf-imagemagick Build Status
Io mracos/asdf-io Build
Jsonnet Banno/asdf-jsonnet Build Status
Java skotchpine/asdf-java Build Status
Julia rkyleg/asdf-julia Build Status
Kops Antiarchitect/asdf-kops Build Status
Kotlin missingcharacter/asdf-kotlin Build Status
Ksonnet Banno/asdf-ksonnet Build Status
Kubecfg Banno/asdf-ksonnet Build Status
Kubectl Banno/asdf-kubectl Build Status
Kubesec vitalis/asdf-kubesec Build Status
LFE vic/asdf-lfe Build Status
Link (system tools) vic/asdf-link Build Status
Logtalk LogtalkDotOrg/asdf-logtalk Build Status
Lua Stratus3D/asdf-lua Build Status
LuaJIT smashedtoatoms/asdf-luaJIT Build Status
Maven skotchpine/asdf-maven Build Status
Mill vic/asdf-mill Build Status
Minikube alvarobp/asdf-minikube Build Status
MongoDB sylph01/asdf-mongodb Build Status
Nim rfrancis/asdf-nim Build Status
Node.js asdf-vm/asdf-nodejs Build Status
Nomad Banno/asdf-hashicorp Build Status
OCaml vic/asdf-ocaml Build Status
OpenResty smashedtoatoms/asdf-openresty Build Status
Packer Banno/asdf-hashicorp Build Status
PHP odarriba/asdf-php Build Status
Postgres smashedtoatoms/asdf-postgres Build Status
protoc paxosglobal/asdf-protoc Build Status
Python danhper/asdf-python Build Status
R iroddis/asdf-R Build Status
Racket vic/asdf-racket Build Status
Rebar Stratus3D/asdf-rebar Build Status
Redis smashedtoatoms/asdf-redis Build Status
Riak smashedtoatoms/asdf-riak Build Status
Ruby asdf-vm/asdf-ruby Build Status
Rust code-lever/asdf-rust Build Status
SBT lerencao/asdf-sbt Build Status
Scala mtatheonly/asdf-scala Build Status
Serf Banno/asdf-hashicorp Build Status
SQLite cLupus/asdf-sqlite Build Status
SWIProlog mracos/asdf-swiprolog Build Status
Terraform Banno/asdf-hashicorp Build Status
Terragrunt td7x/asdf/terragrunt/ pipeline status
TFLint RykHawthorn/asdf-tflint Build Status
Vault Banno/asdf-hashicorp Build Status
.Net Core emersonsoares/asdf-dotnet-core Build Status

Who needs this tool

Everyone.

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
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
asdf list-all dotnet-core

# Install a particular version(s)
asdf install ruby 2.5.0
asdf install ruby 2.5.3
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

# Bind up some tools/versions
asdf local ruby 2.5.0
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 😊