background grid image
Image for post changelog-determinate-nix-342
May 6, 2025 by Luc Perkins

Changelog: deprecating channels and indirect flake references

We’re excited to announce the release of Determinate Nix 3.4.2, based on version 2.28.3 of upstream Nix.

In our last Determinate Nix release we announced a bunch of fun new stuff, like JSON logging and a new set of capabilities to handle hash mismatches. This time around, the vibe is a bit different, as we’ve opted to deprecate two capabilities in Nix:

Deprecating channels

For a good chunk of Nix’s life, channels were the way to do things. If you needed to evaluate expressions from a Nix project, such as Nixpkgs, you added a channel for it and periodically updated that channel to see newer Git commits.

Channels worked well enough but they always carried the grievous drawback that two systems looking at the same Nix code could “see” two different Nix expressions because their respective channels had been updated to different commits—which we believe goes firmly against the grain of Nix’s worldview. There’s an additional problem that every user on a system gets their own channels (including the root user) and the root user’s channels are inherited by all users (but not the other way around)—another source of persistent confusion. For these and other reasons, we announced our intention to deprecate channels in this issue.

This command, for example, would build different versions of ponysay from different commits of Nixpkgs on different machines unless those machines somehow managed to coordinate their channels:

nix-build command involving an unpinned Nixpkgs
nix-build --expr "(import <nixpkgs> {}).ponysay"

Although projects like niv helped the situation by providing a basic pinning mechanism, Nix deserved to have the reproducibility problem resolved at a more fundamental level—Nix deserved flakes.

From the beginning of our life as a company, we at Determinate Systems have believed that flakes are the future of Nix for a variety of reasons, but foremost because they pin your Nix dependencies at all times using a flake.lock file, overcoming the core deficit of channels. Now that flakes have been stabilized in Determinate Nix, we’re ready to begin the process of deprecating channels.

In Determinate Nix 3.4.2, this means two things:

  1. The nix-channel now emits a deprecation warning any time you use it.
  2. Both the nix CLI and the nix-build tool now emit warnings whenever you perform any actions related to channels.

This nix-build command, for example, still works:

nix-build command emitting deprecation warning
nix-build -I nixpkgs=channel:nixos-24.11 '<nixpkgs>' -A ponysay
nix-build will also be deprecated eventually

The nix-build command no longer performs any important functions now that unified Nix CLI has been stabilized in Determinate Nix. We still install it for you in case you still have nix-build invocations in your scripts but we intend to phase it out.

But because it uses the nixos-24.11 channel, it emits this warning:

nix-channel deprecation warning
warning: Channels are deprecated in favor of flakes in Determinate Nix. Instead of 'channel:nixos-24.11', use 'https://nixos.org/channels/nixos-24.11/nixexprs.tar.xz'. See https://zero-to-nix.com for a guide to Nix flakes. For details and to offer feedback on the deprecation process, see: https://github.com/DeterminateSystems/nix-src/issues/34.

This unified nix CLI command also emits a similar deprecation warning because it uses a channel:

Unified CLI command emitting deprecation warning
nix build --file '<nixpkgs>' --nix-path nixpkgs=channel:nixos-24.11 ponysay

What we haven’t yet deprecated is lookup paths like <nixpkgs>. So this command works without emitting a warning:

Unified CLI command emitting no warning
nix build --file '<nixpkgs>' ponysay

But it’s important to note that it works because Determinate Nix’s default settings contain an extra-nix-path setting that sets the value of <nixpkgs> to a flake reference:

/etc/nix/nix.conf
extra-nix-path = nixpkgs=flake:https://flakehub.com/f/DeterminateSystems/nixpkgs-weekly/*.tar.gz

Commands like this also still work because they implicitly refer to the lookup value set in extra-nix-path:

Terminal window
nix build --impure --expr '(import <nixpkgs> {}).cowsay'

While we don’t necessarily encourage using the <nixpkgs> lookup path for new things, we know that many of you may have bits of Nix logic that use references like this and we want to continue to support this use case for now.

Deprecating indirect flake references

Nix with flakes has, from its inception, offered a flake registry that enables you to map indirect flake references to real flake references, such as nixpkgs to https://flakehub.com/f/NixOS/nixpkgs/*. With this mapping in place, these two commands would be equivalent:

Terminal window
# With full reference
nix flake show "https://flakehub.com/f/NixOS/nixpkgs/*"
# With implicit reference
nix flake show nixpkgs

The flake registry, which you can manipulate using the nix registry command, also enables you to use implicit references in flakes themselves. In this example, the URL for the nix flake input maps to whatever is in the flake registry:

flake.nix
{
inputs.nix.url = "nix/2.28.3";
outputs = { self, nix, ... }: {
# your outputs
};
}

This capability also enables you to forgo specifying inputs entirely:

flake.nix
{
outputs = { self, nixpkgs, ... }: {
# your outputs
};
}

We at Determinate Systems think that the former use case for implicit flake references—providing “shortcut” CLI commands—is quite reasonable.

But we don’t think that indirect references inside of flakes are reasonable. In fact, we’ve seen this as an ill-conceived misfeature for years because it produces a hole in flakes’ reproducibility guarantees, as the reference can resolve to different things depending on what’s in the registry. Although this becomes less of an issue when the indirect reference is resolved to a direct reference and written to the flake.lock file, indirect references still run against the spirit of flakes.

We announced our intention to deprecate indirect flake references in flake.nix files in this issue, and in Determinate Nix 3.4.2 we’ve made some changes to that effect.

This command still works…

Indirect flake references on the command line
nix run nixpkgs#cowsay -- Moooo

…but you will see a warning if you run commands against this flake.nix file…

flake.nix
{
outputs = { self, nixpkgs, ... }: {
# your outputs
};
}

…as well as this one:

flake.nix
{
inputs.nixpkgs.url = "nixpkgs";
outputs = { self, nixpkgs, ... }: {
# your outputs
};
}

The warning looks like this, providing a hint to how you can address the issue:

Indirect flake reference warning
warning: Flake input 'nixpkgs' uses the flake registry. Using the registry in flake inputs is deprecated in Determinate Nix. To make your flake future-proof, add the following to '/nix/store/96y77qcpivmvskagnd94hgqczrgcq2w6-source/flake.nix':
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
For more information, see: https://github.com/DeterminateSystems/nix-src/issues/37

In the future we intend to completely prohibit indirect flake references in flakes.

How to upgrade or install

If you already have Determinate Nix installed, you can upgrade to 3.4.2 with one Determinate Nixd command:

Upgrade command for version 3.4.2
sudo determinate-nixd upgrade

If you don’t yet have Determinate Nix installed, you can install it on macOS using our graphical installer:

Logo for graphical installer

Install Determinate Nix on macOS now

Apple Silicon and Intel

On Linux:

Install Determinate Nix on Linux
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
sh -s -- install --determinate

On NixOS, we recommend using our dedicated NixOS module.

Implications

Sometimes less really is more. Here at Determinate Systems, we’re on a mission to modernize Nix and make it not just suitable but rather indispensable for a wide range of enterprise use cases. Sometimes, that will mean adding scintillating new features that expand the range of what Nix can do. Other times, like today, it will mean engaging in some careful pruning.


Share
Avatar for Luc Perkins
Written by Luc Perkins

Luc is a technical writer, software engineer, and Nix advocate who's always on the lookout for qualitatively better ways of building software. He originally hails from the Pacific Northwest but has recently taken to living abroad.

Would you like access to private flakes and FlakeHub Cache?

Sign up for FlakeHub