Blog
Extending Flox with Nix Flakes
Steve Swoyer | 24 July 2024
With the latest release of Flox, you can now define and install software packages as Nix flakes!
This lets you take advantage of the most powerful features in Nix, the proven open-source package manager, to build rich environments without resorting to complex workarounds. All you’ve got to do is include a reference to a flake.nix
in your Flox environment’s manifest.toml
.
Flakes in Flox give you more flexibility, and a compelling new option, in situations where:
-
You need something special. The Flox Catalog has almost everything, with 3+ years of history and more than 1 million package/version combinations. But sometimes you need something it doesn’t have—whether it’s a legacy version of a package or a cutting-edge release that isn’t yet available.
-
You need to do something special. You can use flakes to define package overrides, provide special build instructions, or create unique combinations of components. There’s no need to build advanced logic into the
[hook]
or[profile]
sections of Flox manifests to customize the behavior of packages. Environments run more predictably and are easier to maintain.
Anyway you look at it, this is a powerful new feature.
Why Flakes in Flox?
Up to now we've focused on abstracting much of the complexity—and almost all of the learning curve—involved in scaling Nix across an organization. Flox makes it simple to install packages, create reproducible environments, and compose layered, multi-application runtimes. It’s designed to be used by people who are not Nix experts.
Support for flakes in Flox is different.
We engineered this feature for those who already understand Nix. Flakes support is a nuts-and-bolts feature that probably won't matter to most Flox users, but will matter a great deal to Nix experts who rely on Flox to scale Nix across their teams.
Nix experts can now ship rich, reproducible software environments to their users with Flox—without having to take on the additional burden of teaching Nix.
Example 1: Using Flakes to Install a Missing Version
Let’s briefly explore how this works. And why it’s so neat!
Say you need a quite specific version of Node.js—20.13.1, which is missing from the Flox Catalog.
Not that the catalog doesn’t have plenty of versions of Node.js:
Or even plenty of versions of Node.js 20.x:
It just doesn’t have that exact version of Node. What can you do? In the past, you probably would have...downloaded Node manually on every system where you needed it, then managed the inevitable drift over time.
Now, you can write a Nix flake that installs the exact version you need, Node 20.13.1, and add it to your Flox environment alongside your other project requirements.
Here's an example flake that does exactly that:
We have made this flake available to Flox by placing it into a repository on GitHub: https://github.com/flox-examples/nodejs
If you are not already working inside a Flox environment, you can create a new one by running flox init
in your project folder.
To add this new flake to your environment, run flox edit
and add it to the [install]
section of the manifest. Here’s what this looks like using our example flake:
In the example above, the nodejs
bit can be anything of your choosing, but we recommend matching the pname
of the flake. As a value, provide the flake location in the format github:<owner>/<repo>
. That’s it.
Once you save your changes, the Flox environment will automatically build the flake:
When it is successful, you will get the familiar green checkmark emoji:
And you will be able to activate the environment and access the version of Node you needed:
Just for completeness’ sake, here’s our flake running in macOS on an Intel system:
Example: Using Flakes to Change Package Behavior
Sometimes it’s not that a package is missing from the Flox Catalog, it’s that there is a package that needs to be modified or augmented using a Nix expression.
VS Code is a great example of this. The package vscode-with-extensions
is designed to be used with overrides, which allow you to specify which VS Code extensions are made available. This can be useful for those situations where you need to create a very specific, repeatable IDE experience.
This example flake contains VS Code combined with Jupyter Notebook extensions.
You can use this flake by editing your manifest.toml
and adding it to the [install]
section, just like we saw in the first example.
But there's an easier way! This time, we’ll show you how you can install it from the command line:
Once you activate this environment and run code --list-extensions
, you'll see that only the required extensions are included.
You can easily share your flake-enriched Flox environment just by pushing it to FloxHub.
You can flox pull
it from any other supported system and it'll run, no questions asked. But you can also activate it remotely, without installing it, on any supported system. Just by doing this:
This gives you an ephemeral Flox environment you can activate at a moment's notice, use, and exit—without having to clean anything up.
Next-Level Flox with Flakes
Flox can now extend the power of Nix into your workflow, making it easier for you to deliver rich environments that are portable, reliable, and reproducible. Flox has always allowed you to create advanced build environments, or complex, multi-application runtimes, but sometimes this required complicated, shell-specific logic in your manifests. No more.
Flakes in Flox make it easier for you to scale Nix across your org. It's simplicity emerging from complexity.
So if you’re a Nix user and you haven’t tried Flox, check it out! You can download it here.