ejpcmac

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.nix lets you tell other developers what’s exactly needed. It is even more powerful than .tool-versions as you can set other binary dependencies and try reproducibility thanks to nix-shell --pure;

However:

  • there is no automatic context switching. You can then forget to nix-shell and 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

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

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

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.

Where Next?

Popular in Discussions Top

Rustixir
Hi everyone, im working on find best language/framework/system for high concurrency, high performance and stable performance after wor...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
sashaafm
Piggy backing a bit on @dvcrn topic BEAM optimization for functions with static return type?, I’ve been trying to understand in a deeper ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19204 150
New
hazardfn
I suppose this question is effectively hackney vs. ibrowse but we are at a point in our project where we have to make a choice between th...
New
Qqwy
I would like to spark a discussion about the static access operator: .. For whom does not know: it is used in Elixir to access fields of...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
tomekowal
Hey guys! I want to create a toy project that shows a chart of temperature over time and updates every 5 seconds. I feel LiveView is per...
New
paulanthonywilson
I like Umbrella projects and pretty much always use them for personal Elixir stuff, especially Nerves things. But I don’t think this is ...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

We're in Beta

About us Mission Statement