# Using Juliaup on NixOS (2025 edition)

**URL:** <https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250>\
**Category:** General Usage\
**Tags:** nixos\
**Created:** [June 26, 2025, 6:54pm UTC](https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250 "2025-06-26T18:54:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 26, 2025, 6:54pm UTC](https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250/1 "2025-06-26T18:54:14Z")

</div>

Hey Julia friends. I’ve been trying to figure this out this morning in response to a student who is using NixOS and has convinced me to give it a try. In general on NixOS nothing is in the filesystem where things expect them to be (like in /lib or /usr/lib/ or /usr/bin/ or anything like that).

This means if you download precompiled binaries off the internet they generally won’t run. So if you want to use juliaup in your home directory on a NixOS machine, here’s how I got it working (apparently, tested to work for some very mild test cases).

1. enable nix-ld on your NixOS config via `programs.nix-ld.enable = true;`
2. Make sure you have a .bashrc file (might not if you have a brand new machine, if needed do `echo "" > ~/.bashrc`
3. install juliaup according to the instructions on [julialang.org](http://julialang.org)
4. run julia via the following command (or create a shell script)

```julia
NIX_LD_LIBRARY_PATH=~/.julia/juliaup/julia-1.11.5+0.x64.linux.gnu/lib/julia julia

```

nix-ld uses this environment variable to add to the “real” LD\_LIBRARY\_PATH when it loads julia, thereby avoiding having you link to some system version of stuff… In particular without it you’ll get an error about libcurl when doing package operations. [Vscode julia language server cannot load on recent nixos](https://discourse.julialang.org/t/vscode-julia-language-server-cannot-load-on-recent-nixos/125352)

Now, you’re going to have to be responsible for changing this path when you update julia. So maybe make yourself a ~/bin/julianix script and update the script when you update julia.

Have a good time using Julia on NixOS!

EDIT: added this little shell script which auto-determines the directory from the default julia:

```julia
#!/usr/bin/env bash

VERS=$(juliaup status | sed -n -e "s/ *\*.* 1/1/p")

NIX_LD_LIBRARY_PATH=~/.julia/juliaup/${VERS}/lib/julia ~/.juliaup/bin/julia "$@"

```

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 26, 2025, 7:23pm UTC](https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250/2 "2025-06-26T19:23:23Z")

</div>

> [@dlakelan](#):
>
> a student who is using NixOS and has convinced me to give it a try. In

It may be OT, but would me nice to have a summary of these arguments.. 🙂

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 26, 2025, 7:31pm UTC](https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250/3 "2025-06-26T19:31:32Z")

</div>

The main reason to use NixOS is that you can declare what you want installed in a file, and it will build that installation for you. Also, if you declare stuff that didn’t work, it is transactional so you can roll back to the previous build. I have a lot of machines I need to administer (like 20 total) so being able to centralize how each one is configured and adjust it in a text file and push it out is super useful.

For the student I think it was more about making his PhD project reproducible via the nix shell stuff, which is kind of user-level environment similar to julia’s environments except for the whole project not just the julia part.

---

<div class="post-metadata">

**Author:** ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)\
**Post date:** [September 12, 2026, 7:28pm UTC](https://discourse.julialang.org/t/using-juliaup-on-nixos-2025-edition/130250/4 "2026-09-12T19:28:43Z")

</div>

For those wanting a fully declarative Nix approach (no nix-ld, no upstream installer), I packaged juliaup as a Nix flake: [s-celles/juliaup-nix](https://github.com/s-celles/juliaup-nix)

The approach: build juliaup from Rust source via `rustPlatform.buildRustPackage` — no prebuilt binaries, no patchelf, fully reproducible.

Two outputs:

- `packages.juliaup` — the juliaup CLI (system package)
- `packages.julia` — a julia dispatcher wrapper (user package)

The wrapper exists because juliaup uses `current_exe()` (resolves symlinks via `/proc/self/exe`) to decide whether to launch Julia or show its own CLI. A plain `julia → juliaup` symlink always resolves to the store path, so juliaup sees itself as `juliaup`. The wrapper reads `~/.julia/juliaup/juliaup.json` with `jq` and `exec`s the correct Julia binary directly.

NixOS / Home Manager setup:

```nix
# flake.nix inputs
juliaup-nix = {
  url = "github:s-celles/juliaup-nix";
  inputs.nixpkgs.follows = "nixpkgs";
};

# system — juliaup CLI only
environment.systemPackages = [
  inputs.juliaup-nix.packages.${system}.juliaup
];

# user — julia wrapper in home.packages, NOT systemPackages
# (avoids binary conflict with julia-bin pulled transitively by quarto etc.)
home.packages = [
  inputs.juliaup-nix.packages.${system}.julia
];

```

After rebuild:

```bash
juliaup add release && juliaup default release
julia --version # works

```

Works on any platform supported by Rust + nixpkgs (`eachDefaultSystem`).

* * *

Edit: 2026-09-15  
An update on using [s-celles/juliaup-nix](https://github.com/s-celles/juliaup-nix) with NixOS:

Building `juliaup` from Rust source via `rustPlatform.buildRustPackage` actually builds **both** binaries:

- `juliaup` (the version manager CLI)
- `julia` (the official Rust `julialauncher` multiplexer)

Because `packages.juliaup` provides the real `julialauncher` binary, **no wrapper script or symlink workaround is needed anymore**. The launcher correctly handles channel switching (e.g. `julia +1.10`, `julia +lts`, `julia +release`).

### 1. Setup in `configuration.nix`

Since `juliaup` downloads standard dynamically linked Linux binaries into `~/.julia/juliaup/`, NixOS needs `programs.nix-ld` to run them:

```nix
# flake.nix inputs
juliaup-nix = {
  url = "github:s-celles/juliaup-nix";
  inputs.nixpkgs.follows = "nixpkgs";
};

# NixOS module
environment.systemPackages = [
  inputs.juliaup-nix.packages.${pkgs.stdenv.hostPlatform.system}.juliaup
];

# Dynamic loader for binaries downloaded by juliaup
programs.nix-ld = {
  enable = true;
  libraries = with pkgs; [
    stdenv.cc.cc.lib
    zlib
    openssl
    curl
    libssh2 # Required for Julia 1.10 (LTS) LibCURL compatibility!
  ];
};

```

> **Important tip for Julia 1.10 (LTS):** If you include `curl` in `programs.nix-ld.libraries`, you **must** also include `libssh2`. Otherwise, Nixpkgs’s `libcurl.so.4` will attempt to link against Julia 1.10’s older bundled `libssh2.so.1`, leading to a symbol resolution error (`undefined symbol: libssh2_session_callback_set2`).

### 2. Usage

After `nixos-rebuild switch`:

```bash
# Install channels
juliaup add release && juliaup default release
juliaup add lts

# Channel switching works out-of-the-box
julia # Default (release)
julia +1.10 # LTS
julia +lts # LTS

```

_(Note: for those who still want a 100% store-pinned setup without `nix-ld`, the flake also exposes pre-patched binaries like `packages.julia-lts` and `packages.julia` built with `autoPatchelfHook`)._
