# Angle brackets in a Nix flake world

**URL:** https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855
**Category:** Links
**Created:** [August 10, 2025, 10:08pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855 "2025-08-10T22:08:20Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![fzakaria](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fzakaria/32/2643_2.png) [@fzakaria](https://discourse.nixos.org/u/fzakaria)
#### Post date: [August 10, 2025, 10:08pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/1 "2025-08-10T22:08:20Z")

</div>

> **[Angle brackets in a Nix flake world](https://fzakaria.com/2025/08/10/angle-brackets-in-a-nix-flake-world)**
>
> At DEFCON33, the Nix community had its first-ever presence via nix.vegas and I ended up in fun conversation with tomberek 🙌.

---

<div class="post-metadata">

### Author: ![MagicRB](https://discourse.nixos.org/user_avatar/discourse.nixos.org/magicrb/32/6884_2.png) [@MagicRB](https://discourse.nixos.org/u/MagicRB)
#### Post date: [August 11, 2025, 6:24am UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/2 "2025-08-11T06:24:05Z")

</div>

Nice write up, the use of the angle bracket syntax is interesting. Though i think i disagree that adding `buitins.currentFlake` would be pure. It’s also very very hard to define, when it should switch a flake input of the toplevel flake. So I’m not sure such a chabge would be a net positive

---

<div class="post-metadata">

### Author: ![eljamm](https://discourse.nixos.org/user_avatar/discourse.nixos.org/eljamm/32/16466_2.png) [@eljamm](https://discourse.nixos.org/u/eljamm)
#### Post date: [August 11, 2025, 12:30pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/3 "2025-08-11T12:30:27Z")

</div>

This is quite interesting indeed, but why don’t you use `self` instead of `getFlake`?

> **flake.nix**
>
> ```nix
> {
> inputs = {
> nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
> nixpkgslib.url = "github:nix-community/nixpkgs.lib";
> };
> description = "Trivial flake that returns a string for eval";
> 
> outputs =
> {
> nixpkgslib,
> nixpkgs,
> self,
> }:
> {
> __findFile =
> nixPath: name:
> let
> lib = nixpkgslib.lib;
> in
> lib.getAttrFromPath (lib.splitString "." name) self;
> 
> hello = "Hello from a flake!";
> example = builtins.scopedImport self ./default.nix;
> };
> }
> 
> ```

> **default.nix**
>
> ```nix
> <outputs.hello> + " and welcome to Nix!"
> 
> ```

```shellSession
$ nix eval .#example
"Hello from a flake! and welcome to Nix!"

```

---

<div class="post-metadata">

### Author: ![fzakaria](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fzakaria/32/2643_2.png) [@fzakaria](https://discourse.nixos.org/u/fzakaria)
#### Post date: [August 11, 2025, 12:48pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/4 "2025-08-11T12:48:46Z")

</div>

Thank you that’s great.  
Originally I had the lookup in a different file before I discovered scopedImport

I’ll update the example with this 🤌👌

---

<div class="post-metadata">

### Author: ![llakala](https://discourse.nixos.org/user_avatar/discourse.nixos.org/llakala/32/38325_2.png) [@llakala](https://discourse.nixos.org/u/llakala)
#### Post date: [August 11, 2025, 1:12pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/5 "2025-08-11T13:12:59Z")

</div>

While I appreciate the concept of new angle bracket syntax, I don’t think the Nix language needs flake-specific syntax. Flakes have been adopted by the majority of the community - but NIX\_PATH was previously adopted by the majority of the community. The shortcomings of flakes are [well-documented](https://jade.fyi/blog/flakes-arent-real/), and they are still experimental for established reasons. Even the biggest proponents of Flake stabilization acknowledge that [future iterations on Flakes will happen](https://discourse.nixos.org/t/determinate-nix-3-0/61202/129), and plan on supporting them.

I don’t think entrenching ourselves further in flakeland is the right move. I’d prefer to see angle brackets used for something more meaningful, like [providing a module system with faster evaluation](https://gist.github.com/edolstra/29ce9d8ea399b703a7023073b0dbc00d).

---

<div class="post-metadata">

### Author: ![aanderse](https://discourse.nixos.org/user_avatar/discourse.nixos.org/aanderse/32/1420_2.png) [@aanderse](https://discourse.nixos.org/u/aanderse)
#### Post date: [August 11, 2025, 1:13pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/6 "2025-08-11T13:13:41Z")

</div>

as always another cool article from @fzakaria 🕶

personally i prefer a simplified `__findFile` like this:

```auto
__findFile = nixPath: name: inputs.${name};

```

that is… map each flake input, but not output  
my reasoning is that this is a more natural progression from channels to flakes and keeps the same semantics - flake inputs are an extension/improvement/natural progression of channels

but then again… i don’t like most flake outputs, so i guess i have a bias there… 😅

---

<div class="post-metadata">

### Author: ![fzakaria](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fzakaria/32/2643_2.png) [@fzakaria](https://discourse.nixos.org/u/fzakaria)
#### Post date: [August 11, 2025, 4:07pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/7 "2025-08-11T16:07:20Z")

</div>

Thanks for the kind words.

The problem with ${name} is that if you do “a.b” it puts it as a single attribute quoted. I guess for inputs it may not matter.

Why support output?  
Well I want to access my own packages or modules sometimes instead of through an overlay

---

<div class="post-metadata">

### Author: ![fzakaria](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fzakaria/32/2643_2.png) [@fzakaria](https://discourse.nixos.org/u/fzakaria)
#### Post date: [August 11, 2025, 4:10pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/8 "2025-08-11T16:10:13Z")

</div>

I just pushed an update to the blog with your improvement – thank you.

---

<div class="post-metadata">

### Author: ![leana8959](https://discourse.nixos.org/user_avatar/discourse.nixos.org/leana8959/32/33046_2.png) [@leana8959](https://discourse.nixos.org/u/leana8959)
#### Post date: [August 19, 2025, 1:51pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/9 "2025-08-19T13:51:55Z")

</div>

The ability to use angle brackets is very interesting, though `scopedImport` has huge performance penalty (iirc it disables memoisation). Some testing with `nix-instantiate` (I don’t use flake but npins) shows that the evaluation time goes from 17 seconds to almost 30 seconds, doubling the evaluation time…

---

<div class="post-metadata">

### Author: ![tripleo](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/t/41988e/32.png) [@tripleo](https://discourse.nixos.org/u/tripleo)
#### Post date: [October 4, 2025, 5:07pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/10 "2025-10-04T17:07:39Z")

</div>

might be slighlty off topic:

> <https://gist.github.com/edolstra/29ce9d8ea399b703a7023073b0dbc00d#solution-configurations>

---

<div class="post-metadata">

### Author: ![SergeK](https://discourse.nixos.org/user_avatar/discourse.nixos.org/sergek/32/2972_2.png) [@SergeK](https://discourse.nixos.org/u/SergeK)
#### Post date: [October 4, 2025, 8:24pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/11 "2025-10-04T20:24:35Z")

</div>

> _eventual deprecation of `NIX_PATH`?_

❓ 🫠

---

<div class="post-metadata">

### Author: ![aanderse](https://discourse.nixos.org/user_avatar/discourse.nixos.org/aanderse/32/1420_2.png) [@aanderse](https://discourse.nixos.org/u/aanderse)
#### Post date: [October 4, 2025, 8:48pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/12 "2025-10-04T20:48:53Z")

</div>

that document was presented _forever_ ago at a nixcon for ideas on where to head… it is vaporware now, not going to happen

* * *

as far as deprecating `NIX_PATH` though… i bet some people actually want to do that - i hope that won’t happen

recently i started playing around with [lon](https://github.com/nikstur/lon) (❤ @nikstur) and started utilizing angle brackets again after having switched to flakes many years ago now

one of my `shell.nix` files looks like as an experiment:

```auto
let
  sources = import ./lon.nix;

  pkgs = import sources.nixpkgs { };
in
  pkgs.mkShell {
    shellHook = ''
      export NIX_PATH=${pkgs.lib.concatMapAttrsStringSep ":" (k: v: "${k}=${v}") sources}
    '';
  }

```

i hooked that up to `direnv` and now whenever i enter that project directory i can access `<nixpkgs>` in a well defined way - whether in `repl` or something like `nixos-rebuild`, everything has access to `NIX_PATH`

i haven’t been using this long enough to decide how much i like it yet… but it has been a blast from the past at least

---

<div class="post-metadata">

### Author: ![bme](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@bme](https://discourse.nixos.org/u/bme)
#### Post date: [October 5, 2025, 4:46pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/14 "2025-10-05T16:46:29Z")

</div>

I really think NIX\_PATH is great. It supremely useful when mucking about with the repl to just say “gimme the nixpkgs in context” whether that’s system wide, or in some project, it’s useful shorthand. I use it _all the time_ for answering “what about??” repl questions in the global system context. If I want to turn into something stable/shareable, well I can just copy the system nixpkgs pin and move from ephemeral to permanent.

NIX\_PATH \<3 for ever!

---

<div class="post-metadata">

### Author: ![Lord-Valen](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lord-valen/32/8235_2.png) [@Lord-Valen](https://discourse.nixos.org/u/Lord-Valen)
#### Post date: [October 10, 2025, 1:34am UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/15 "2025-10-10T01:34:10Z")

</div>

I think `builtins.scopedImport self` is rather reckless. You could accidentally override a number of things. It would be safer to do something like this:

```nix
{
  outputs =
    { self, nixpkgs, ... }:
    let
      inherit (nixpkgs) lib;
      scope = {
        __findFile = _: name: lib.getAttrFromPath (lib.splitString "." name) self;
      };
    in
    {
      scoped = builtins.scopedImport scope ./default.nix;
    };
  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
  };
}

```

If you were to define something like `import` in the outputs of the previous example (not intending to override the `import` global), you might just break all subsequent calls to `import`. Obviously, I don’t think anyone would actually do _that_ (at least, I hope not), but I’m sure you can see how similar things _could_ happen:

```nix
# scoped.nix or selfed.nix
{
  pkgs = import <inputs.nixpkgs> { };
}

# flake.nix
{
  outputs =
    { self, nixpkgs, ... }:
    let
      inherit (nixpkgs) lib;
      scope = {
        __findFile = _: name: lib.getAttrFromPath (lib.splitString "." name) self;
      };
    in
    {
      inherit (scope) __findFile;

      # Oh no! Unanticipated name conflict!
      # If we use `self` as the scope, this overrides the `import` global.
      import = import nixpkgs { };

      # In `selfed.nix`, `import` is a set.
      # That causes an error.
      selfed = builtins.scopedImport self ./selfed.nix;

      # In `scoped.nix`, `import` is the builtin function.
      # Everything goes as expected.
      scoped = builtins.scopedImport scope ./scoped.nix;
    };
  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
  };
}

```

It’s littering, at best, because everything in `outputs` becomes global.

---

<div class="post-metadata">

### Author: ![vic](https://discourse.nixos.org/user_avatar/discourse.nixos.org/vic/32/35386_2.png) [@vic](https://discourse.nixos.org/u/vic)
#### Post date: [November 5, 2025, 6:48am UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/16 "2025-11-05T06:48:40Z")

</div>

Hey, @fzakaria

Thanks for your blog post! It served as inspiration for an **experimental feature** in `den`, where we have nested trees of aspects, `den.aspects.foo.provides.bar.provides.baz`, we already had an alias `_` for `provide`, so `den.aspects.foo._.bar._.baz` is not that bad, however using your idea:

`<foo/bar/baz>` becomes `den.aspects.foo.provides.bar.provides.baz` !

See the linked PR bellow:

> **[Have you seen those \`.\_.\` little faces ? · vic/den · Discussion #34](https://github.com/vic/den/discussions/34#discussioncomment-14877216)**
>
> Have you seen those \`.\_.\` little faces ?

---

<div class="post-metadata">

### Author: ![Lillecarl](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lillecarl/32/34279_2.png) [@Lillecarl](https://discourse.nixos.org/u/Lillecarl)
#### Post date: [November 6, 2025, 2:06pm UTC](https://discourse.nixos.org/t/angle-brackets-in-a-nix-flake-world/67855/17 "2025-11-06T14:06:01Z")

</div>

You can always copy to store without flakes, talking about deprecating NIX\_PATH is blasphemy and trying to bait mindset DJT style.

I don’t know what Stockholm syndrome flake users are experiencing but I really don’t get it. They just add more rules and limits and force you to reimplement every attrset N times for chasing some purity nirvana that’s entirely useless in practice, where are the gains!?
