this post was submitted on 22 Dec 2025
6 points (100.0% liked)

Nix / NixOS

2572 readers
17 users here now

Main links

Videos

founded 2 years ago
MODERATORS
 

I'm starting to have a lot of flake inputs in my flake.nix file, and it's starting to get really cluttered. I'm wondering if there's a way to separate my inputs into multiple files so it looks cleaner. I've tried to look it up but couldn't really find anything abt it

Edit: Well as it turns out it's not something possible yet, apparently the flake.nix file isn't parsed like regular nix files and doesn't support stuff like import

top 12 comments
sorted by: hot top controversial new old
[–] hallettj@leminal.space 2 points 2 weeks ago* (last edited 2 weeks ago) (2 children)

I think you can use import to load the expression from each file, and the // operator to combine imported attribute sets. Like this:

Edit: This doesn't work - see replies

# flake.nix
{
  inputs =
    import ./inputs/nixpkgs.nix //
    import ./inputs/nix-index.nix;

  # ...
}
# inputs/nixpkgs.nix
{
  nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
  nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
}
# inputs/nix-index.nix
{
  nix-index-database = {
    url = "github:Mic92/nix-index-database";
    inputs.nixpkgs.follows = "nixpkgs";
  };
}
[–] Klaymore@sh.itjust.works 2 points 2 weeks ago (1 children)

One note about // is that it doesn't deep combine attribute sets, so if you set the .url in one and .inputs.nixpkgs.follows in another then it will only use the second one. I don't think that matters here but it's tripped me up before. I think lib.mkMerge is the deep recursive alternative.

[–] hallettj@leminal.space 2 points 2 weeks ago* (last edited 2 weeks ago)

Good point! But I think lib.mkMerge only merges options in a module system like the ones used in NixOS, Home Manager, and flake-parts configs. In this situation I think the function to use would be lib.attrsets.recursiveUpdate

[–] claymorwan@lemmy.blahaj.zone 2 points 2 weeks ago (1 children)

I followed how u did it but it doesn't seem to work, i keep getting hit with this error:

error: expected a set but got a thunk at /home/claymorwan/.dotfiles/NixOS/flake.nix:4:3
[–] hallettj@leminal.space 1 points 2 weeks ago* (last edited 2 weeks ago) (1 children)

Whoops! Guess I was wrong. After some experimenting it looks like the flake system parses, but does not evaluate flake.nix to read inputs. I also experimented with string concatenation, and that failed with the same error:

nixpkgs.url = "github:nixos/nixpkgs" ++ "/nixos-25.05"; # error: expected a string or path, but got a thunk

A "thunk" is an expression whose evaluation has been delayed. It's a key piece of lazy evaluation. Remember that every expression in Nix is lazily evaluated.

It looks only literal attribute set, string, and path expressions will work in inputs. I think that means it is not possible to split inputs over multiple files.

[–] claymorwan@lemmy.blahaj.zone 2 points 2 weeks ago

yea i think it may just not be possible yet, looking it up more i've seen people talking abt how a big con of flakes is that flake.nix is not parsed like regular nix files. I'm not sure why they made it work like that but it gets changed eventually cuz that's really too bad we can't do things as simple as imports

[–] algernon@lemmy.ml 2 points 2 weeks ago (1 children)

The way I solved this problem is that I write my flake.nix in a literate-programming style using Org Roam. I have a code block that tangles out into out/flake.nix, which has a <<flake-inputs>> placeholder. I can have any number of code blocks, in any number of Org files that all reference flake-inputs. Thus, my inputs are near other code (& documentation) that uses them, split across dozens of files.

The downside is that you no longer write Nix directly, but have to tangle it out.

[–] claymorwan@lemmy.blahaj.zone 1 points 2 weeks ago (1 children)

first time im earing of Org Roam, but i think i kinda understand, do ya got a repo where i can see how u did it im kinda interested

[–] algernon@lemmy.ml 2 points 2 weeks ago (1 children)
[–] claymorwan@lemmy.blahaj.zone 1 points 2 weeks ago (1 children)

o thanks, i'll take a closer look but for what i've seen so far it kinda looks complex I also flake-part mentioned in some of the commits,i remember seeing it a few times and apparently it can modularize flakes or sum like that, can it modularize inputs too outta curiosity

[–] algernon@lemmy.ml 1 points 2 weeks ago (1 children)

It's complex, because it does a lot of things, and it evolved over the past few years. The basics are very, very simple:

#+begin_src nix :tangle out/flake.nix :noweb no-export :noweb-prefix no :mkdirp t
{
  inputs = {
    <<flake-inputs>>
  };

  outputs = { self, nixpkgs, ... }@inputs: {
    <<flake-outputs>>
  };
}
#+end_src

In some other file, you can then do:

#+begin_src nix :noweb-ref flake-inputs
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
#+end_src

And voila, you now have:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
  };

  // ...rest of the flake
}

How you organize your org documents, is entirely up to you. The trick is that this lets you split it up as you see fit, and you are no longer restricted by what the language or any framework built on top of it can provide.

[–] claymorwan@lemmy.blahaj.zone 1 points 2 weeks ago

o yea now i see better how it works, all i gotta do is learn some emacs stuff and then i should be able to do it, thanks a lot!