ejpcmac
Nix vs asdf for Elixir version management
I have discovered Nix last month and I am currently on my way to migrating to it—both on macOS at home and the full NixOS distrubution at work. Now, I use it for configuration and package management, but I am considering to switch my development workflow to Nix too. Yet, I have some questions regarding the Elixir environment.
I am presently using asdf to manage Erlang and Elixir versions. I like:
- its ease of use,
- the availability of many versions, including pre-releases and all patch versions,
- the way you can set a given version for each project thanks to
.tool-versions, - automatic context switch between directories.
The only drawback I find now is the Erlang compilation dependencies management. I’ve set up an Elixir environment at work on several Linux distributions, and each time I missed some dependencies on the first run. I’m not even sure if I could manage to build Erlang using asdf on NixOS since—as far as I understand—libraries are not available outside of a nix-build. I have tried to do it in a nix-shell, but it kept complaining about OpenSSL not being available, despite it being installed and set in LD_LIBRARY_PATH.
On the other hand, using Nix as part of my Elixir workflow could address these issues. As all build dependencies are automatically managed, there would not be Erlang build issues anymore. A simple shell.nix in my projects would tell what is needed. From my first trials:
-
it is possible to set a given Erlang / Elixir version using a package like
beam.packages.erlangR21.elixir_1_7; -
writing a
shell.nixlets you tell other developers what’s exactly needed. It is even more powerful than.tool-versionsas you can set other binary dependencies and try reproducibility thanks tonix-shell --pure;
However:
-
there is no automatic context switching. You can then forget to
nix-shelland use mistakenly a globally-installed Elixir version instead of the project one. Maybe it is just a habit to get used to, and frequent Nix users do this without thinking about it; -
only the last patch version of each minor version is available, and it seems there are no pre-releases. This can be problematic, especially if you maintain libraries and want to test them on versions to come.
-
new versions seem to be available after a while compared to
asdf.
In addition to these points, I think using Nix for projects is not as easy as asdf when it comes to contributions: asdf is easy to install at the user level and get into, where you need to sudo to install Nix.
Are there some Nix / NixOS users here? What do you think about Nix in the Elixir workflow? How do you address the few points I have noticed? And if you are a NixOS user, how would you use asdf if third-party project uses it?
Most Liked
ejpcmac
An update for future readers: I have completely switched from asdf to Nix lately. It is a joy to use to setup a complete environment, including non-language dependencies you can need to build different kind of projects. I’ve set up standard shell.nix for both standard, Phoenix and Nerves projects. I have also written an article about it which I hope will be useful to Nix newcomers.
shanesveller
I’m a relatively happy Nix user in general, including on OSX and as a Linux desktop via NixOS, but I would be very unhappy teaching most people to use it, even those who are able to effectively adapt to both Elixir and ASDF. It’s a lot to ask for little return unless you already find it academically interesting. It has a lot of parallels in my mind to my use of Emacs - I personally find it very powerful and compelling, but struggle to articulate well to others who are skeptical, or who have different levels of tenacity in the face of ~user-unfriendly~ complex software.
I will also say that very specifically the abstractions used in the BEAM packaging within nixpkgs are over-abstracted from my POV. They are probably very useful/powerful to the internal/official maintainers, but are sort of a nightmare to consume as someone who is literate with the syntax but not an expert. If you’re not sure what I mean, try to figure out how to use a Nix overlay or shell.nix to install a particular patch release of Erlang and of Elixir, without it having been packaged already. You can’t use a simple override, nor have I found an easy way to otherwise “patch” the URL and checksum of the target download like I can with other languages’ Nix packaging.
I ultimately fell away from using Nix specifically for the BEAM ecosystem and back to ASDF, even when I persist with Nix elsewhere.
For those unfamiliar, here’s an example of shell.nix content:
# 2018-06-26 11:30
# https://d3g5gsiof5omrk.cloudfront.net/nixpkgs/nixpkgs-18.09pre143801.5ac6ab091a4/nixexprs.tar.xz
with import <nixpkgs>{};
let
erlang = beam.packages.erlangR21.erlang;
elixir = beam.packages.erlangR21.elixir;
nodejs = pkgs.nodejs-10_x;
yarn = pkgs.lib.overrideDerivation pkgs.yarn (attrs: rec {
buildInputs = [pkgs.makeWrapper nodejs];
});
in
stdenv.mkDerivation rec {
name = "my_elixir_project";
version = "0.1.0";
buildInputs = [
erlang
elixir
nodejs
yarn
# phoenix_live_reload
pkgs.darwin.apple_sdk.frameworks.CoreFoundation
pkgs.darwin.apple_sdk.frameworks.CoreServices
# postgrex
pkgs.postgresql100
# developer tools
pkgs.direnv
pkgs.gitMinimal
pkgs.hex2nix
];
}
Ankhers
I am actually in the (very slow) process if making the BEAM work better within Nix (I have posted about this elsewhere on the forum before, maybe look for that for some more information). I am writing a tool right now that will convert a rebar3 or mix project into a default.nix file similar to tools for other languages.
Automatic context switching
Like you said, there is none. You will just need to get used to calling nix-shell or some other tool to get where you want. But this isn’t necessarily a bad thing either. You are being explicit about what you want.
Limited versions
This is also true. But I don’t really see having only the latest patch for each minor version available. Everything should be backward compatible (assuming you are not relying on internal functionalty, but there is already a post about that elsewhere). So it is just bug fixes and such.
Time for a new version
Again, true. This is mostly true about any OS package manager. Nix needs to make sure that all of the packages in the ecosystem play nicely together. With that said, I did make it super easy to make your own version of Elixir if it is not found in nixpkgs. Just take a look at how we define v1.7 and the corresponding entry to actually build it. If you need a version that is not listed or has not yet been updated. Feel free to add your own for your project!
Contributions
Just like you do not need asdf installed to contribute to a package that has asdf, you do not NEED to install Nix to contribute to a package that uses it. Just make sure you outline your requirements in your contribution guide.
For the vast majority of uses, I would currently say to stay away from Nix and NixOS for BEAM specific work. Or if you want to use NixOS, use it like a regular linux for the time being (I am doing this for a couple things).
For anyone else that REALLY wants to use Nix and NixOS right now, send me a message and we will see if we can get the BEAM integration moving a little faster.
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








