Installing different versions of Elixir and Erlang

No problem.

Here’s your original version modified near the end to be specific about which major version of Erlang to use. That may be enough to get you started, if you like.

{
  inputs = {
    nixpkgs = {
      url = "nixpkgs/nixos-23.05";
    };

    unstable = {
      url = "nixpkgs/nixos-unstable";
    };
  };

  outputs = { self, nixpkgs, unstable }: {
    packages."x86_64-darwin".default = let
      pkgs = nixpkgs.legacyPackages."x86_64-darwin";
      unstablePkgs = unstable.legacyPackages."x86_64-darwin";
    in pkgs.buildEnv {
      name = "my-packages";
      paths = with pkgs; [
        curl
        git
        unstablePkgs.beam.packages.erlangR26.elixir_1_15
        unstablePkgs.beam.packages.erlangR26.erlang
      ];
    };
  };
}

Here’s a version that uses my flake module via flake-parts and is based loosely on my non-Phoenix flake template:

{
  inputs = {
    beam-flakes = {
      url = "github:shanesveller/nix-beam-flakes";
      inputs.flake-parts.follows = "flake-parts";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    flake-parts.url = "github:hercules-ci/flake-parts";
    nixpkgs.url = "nixpkgs/nixos-unstable";
  };

  outputs = inputs @ {
    beam-flakes,
    flake-parts,
    ...
  }:
    flake-parts.lib.mkFlake {inherit inputs;} {
      imports = [beam-flakes.flakeModule];

      systems = ["aarch64-darwin" "x86_64-darwin"];

      perSystem = {pkgs, ...}: {
        # options are documented at https://nix-beam-flakes.sveller.codes/options
        beamWorkspace = {
          enable = true;
          devShell.extraPackages = with pkgs; [curl git];
          versions = {
            elixir = "1.15.7";
            erlang = "26.1.2";
          };
        };
      };
    };
}

This uses a flake devShell rather than a package output, so you use nix develop .# to enter that context.

Extra learning topics below, feel free to skip but I’m leaving them as further jumping off points if you decide you have appetite.


The project templates can be used with these commands, which per the Nix CLI behavior should abort if they would overwrite any existing file in your project.

nix flake init -t github:shanesveller/nix-beam-flakes#default
# or
nix flake init -t github:shanesveller/nix-beam-flakes#phoenix

They assume use of direnv + nix-direnv, so if you don’t use those you can erase the .envrc file.


If any x86 Linux users wanted to use my binary cache, please do your own homework about trust, auditability, supply chain attacks, etc. but you can introduce this as a top-level key in your flake, as a sibling to inputs and outputs. Notably in your case, OP, it would be pointless, because I don’t build or push any Darwin artifacts due to GHA limitations (and I don’t have any Intel hardware left).

  nixConfig = {
    extra-substituters = ["https://shanesveller-nix-beam-flakes.cachix.org"];
    extra-trusted-public-keys = [
      "shanesveller-nix-beam-flakes.cachix.org-1:DMWI87/57GNone8wN7dXcqlgdIk36qHfvhXJ/esq5hk="
    ];
  };
2 Likes