Tools Version Manager
Tools Version Manager
Section titled “Tools Version Manager”The nix-versions tool manager is so simple that it does not exist. It is more of a pattern of usage when
combined with nix shell and direnv.
The idea is simple:
No nix-wizardry required, just use plain-text files to specify your tool requirements and let nix-versions produce output that nix shell and direnv can use to give you a stable development environment.
If you already know Nix, and want to use pinned-version packages as inputs for your own Nix Flake
or integrate with state-of-the-art Nix environments like
devenv or devshell, NixOS/nix-darwin/home-manager or any other nix module class,
see our flake generator service.
Target Audience
Section titled “Target Audience”As a Tools Version Manager, the pattern presented on this page can replace 90% of what tools like asdf-vm do,
but with all the benefits you can get from Nix:
All installable tools from Nixpkgs at your fingertips, Reproducibility, Security Checksums, Sandboxed Builds, Remote Builders, Caching, etc.
And of course, pinned version packages by nix-versions.
If you are new to Nix but have used other version managers like nvm, rvm, asdf, mise we want to provide you with an integrated toolset that lets you take advantage of Nix
without mandating you to learn the nix language. By editing plain-text files and reusing your existing .ruby-version, .node-version, etc files, you can cover most of your needs.
Quick Start with direnv
Section titled “Quick Start with direnv”If you already have Nix and direnv installed, you can quickly get an environment ready in no time.
Note that you don’t even need nix-versions installed locally for this to work.
Because the endpoint already resolves the nix installables for you.
# Place this on your .envrcsource_url "https://nix-versions.oeiuwq.com/use_nix_tools.sh/go/ruby" HASHWhere HASH can be obtained with:
direnv fetchurl "https://nix-versions.oeiuwq.com/use_nix_tools.sh/go/ruby"You can obtain package updates by doing direnv reload.
How it works
Section titled “How it works”By playing well with others. Following the UNIX philosophy of doing just ONE thing (listing package versions) and producing plain-text output that can be used by other programs to become part of something bigger.
The Nix Installables output format
Section titled “The Nix Installables output format”By using the --installable (short: -i) option, nix-versions can produce a list of Nix Installables that can be read by nix shell.
nix-versions --installable go@1.24.x ruby@latestOutput:
nixpkgs/de0fe301211c267807afd11b12613f5511ff7433#go_1_24nixpkgs/0d534853a55b5d02a4ababa1d71921ce8f0aee4c#ruby_3_4Reading package specs from a plain-text file
Section titled “Reading package specs from a plain-text file”Instead of giving package specs as command line arguments you can use the --read (short -r) option for reading them from a file.
The file name is not special to nix-versions, but we use the convention of having a .nix_tools file.
nix-versions --read .nix_tools --installableThe .nix_tools file can look like this:
# shell-like comments are ignored.# You can use `pkg@version` as in nix-versions command lineruby@latest # same as `ruby@` or `ruby@*`, ie. no version restriction.
# You can use spaces/tabs after the package name, just like .tool-versions files from asdf.# And it also looks much cleaner.
go >= 1.24 <1.26 # white space/tabs are not significant.nodejs .node-version # read version constraint from an existing file.As you can see from the previous example, you can reuse your existing .ruby-version, .node-version, .tool-versions, etc files that might be already in use in your project.
Entering a nix shell environment
Section titled “Entering a nix shell environment”Now that you have some files like .nix_tools, .node-version from the previous examples, you are ready to enter a nix development shell containing those tools, pinned to their constrained versions.
nix shell $(nix-versions -ir .nix_tools)Automatic environment loading with direnv
Section titled “Automatic environment loading with direnv”Now you might want to load the environment into your existing shell automatically, every time you enter your project directory. The right tool for doing this is direnv.
All you need now is to create the following file $HOME/.config/direnv/lib/use_nix_tools.sh. This file
will install a function that all your projects can use to load their respective environment.
mkdir -p ~/.config/direnv/lib# You can always inspect the downloaded function before installing itcurl "https://nix-versions.oeiuwq.com/use_nix_tools.sh" -o ~/.config/direnv/lib/use_nix_tools.shThen, on your project directory, besides your .nix_tools file, create an .envrc file that will be
detected by direnv.
use nix_toolsAnd you are set! Just direnv allow and enjoy using your tools.
More advanced environments
Section titled “More advanced environments”The Nix ecosystem has much more advanced development environments than those produced by nix shell.
A couple of them are devenv and devshell,
that provide more advanced features than simply loading environment variables.
See our flake generator documentation for how to use pinned packages with these tools.