Edvard
December 7, 2025, 4:29pm
1
I’m aware that this can (maybe should) be done by pinning an old version of nixpkgs. Anyhow I’m struggling to understand why this doesn’t work:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
(elixir.override{
version = "1.13.2";
minimumOTPVersion = "22";
maximumOTPVersion = "24";
erlang = (erlang.override {
version = "24.3.4.17";
});
})
];
}
(pinning to 24 here is just for https://hexdocs.pm/elixir/1.13.2/compatibility-and-deprecations.html , i assume it’s not part of the problem?)
Then
/nix/store/pii4mjz4ycc4sidbv7fy6n724z76qrsm-erlang-24.3.4.17
/nix/store/bwbwyz4yk13wnk3zfx1hwx9v18rl9cw1-elixir-1.13.2
are built. But when I ask for the version:
[nix-shell:~/test]$ realpath $(which elixirc)
/nix/store/bwbwyz4yk13wnk3zfx1hwx9v18rl9cw1-elixir-1.13.2/bin/elixirc
[nix-shell:~/test]$ elixirc --version
Erlang/OTP 27 [erts-15.2.7.3] [source] [64-bit] [smp:22:22] [ds:22:22:10] [async-threads:1] [jit:ns]
Elixir 1.18.4 (compiled with Erlang/OTP 27)
Clearly elixir version is 1.18.4 and OTP 27 which is what i also get by just doing nix-shell -p elixir.
Any pointers to why it builds, and that I still get 1.18.4 would be appreciated.
1 Like
NobbZ
December 7, 2025, 7:30pm
2
Overriding a version does nothing but making you rebuild the old thing with a different name.
You need to override full source.
Though for elixir things are slightly different anyway.
You need a beam package set with the overriden Erlang
Use that to create a proper elixir which again overrides the source.
I will lookup an example later when the kids are in bed.
1 Like
This probably won’t be exactly what you’re looking for, but here’s how I typically setup my Elixir dev flakes:
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs, ... }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
beamPkgs = with pkgs.beam_minimal; packagesWith interpreters.erlang_27;
erlang = beamPkgs.erlang;
elixir = beamPkgs.elixir_1_17;
in
{
devShells."${system}".default = pkgs.mkShell {
buildInputs = [
erlang
elixir
beamPkgs.hex
beamPkgs.elixir-ls
pkgs.inotifyTools
pkgs.nodejs
];
ERL_INCLUDE_PATH = "${erlang}/lib/erlang/usr/include";
ERL_AFLAGS = "-kernel shell_history enabled";
shellHook = ''
# Allow mix to work on local directory
mkdir -p .nix-mix
mkdir -p .nix-hex
export MIX_HOME=$PWD/.nix-mix
export HEX_HOME=$PWD/.nix-hex
export ERL_LIBS=$HEX_HOME/lib/erlang/lib
# Concat paths
export PATH=$MIX_HOME/bin:$PATH
export PATH=$MIX_HOME/escripts:$PATH
export PATH=$HEX_HOME/bin:$PATH
# "Run: `mix archive.install hex phx_new` for phoenix."
'';
};
};
}
The manual has additional information, though you’ve probably already checked that. Not gonna lie, things are a bit awkward right now, ergonomically. I’m not sure if that’s avoidable or not, but rest assured you aren’t the only one who’s had some head-scratchers.
2 Likes
NobbZ
December 8, 2025, 7:04am
4
Yeah, this is exactly what I was referring to yesterday, but I got distracted by my kids and bedtime stories.
Also, I might borrow some parts of the shell hook.
2 Likes
It’s a combination of my own derping around, a blog post (I think?) where somebody had that neat idea for per-project hex storage, and possibly slop at one point or another. I also have one that works for livebook and Nx, mostly, if you want to see it.
1 Like