Imp 😈
Imp maps filesystem structure to Nix attribute sets, .nix file becomes attributes, with nesting following the directory hierarchy. This works for flake outputs, NixOS modules and development environments.
Simple file drop-ins with no explicit import wires are the core of Imp. Add a file (and track with git) and it will be imported and evaluated. Renames and deletions are automatically taken care of during eval.
outputs = inputs: inputs.imp.tree ./src;
# src/foo/bar.nix -> { foo.bar = <contents>; }
Development projects
For a typical dev project, imp generates flake outputs from a directory structure:
nix/
outputs/
perSystem/
packages.d/
cli.nix # packages.cli
lib.nix # packages.lib
devShells.d/
rust.nix # devShells components
lint.nix
formatter.d/
nix.nix # formatter components
rust.nix
checks.nix # checks.*
Fragment directories (.d) merge their contents, so multiple files can contribute to devShells.default or formatter. Configure imp with flake-parts:
{
imports = [ inputs.imp.flakeModules.default ];
imp.src = ./nix/outputs;
}
NixOS configurations
For system configuration, imp adds registries, export sinks, and host declarations:
mod/
os/
base.nix # NixOS modules
audio.nix
hm/
git.nix # Home Manager modules
shell.nix
hosts/
desktop/
default.nix # __host declaration
hardware.nix
networking.nix
users/
alice.nix
Modules export to named sinks by role:
# mod/os/audio.nix
let
mod = { ... }: {
services.pipewire.enable = true;
};
in
{
__exports.desktop.os.value = mod;
__module = mod;
}
Hosts declare which sinks to include:
# hosts/desktop/default.nix
{
__host = {
system = "x86_64-linux";
stateVersion = "24.11";
sinks = [ "shared.os" "desktop.os" ];
hmSinks = [ "shared.hm" "desktop.hm" ];
user = "alice";
};
}
Imp generates nixosConfigurations.desktop, importing the specified sinks and wiring Home Manager. Configuration files in the same directory (hardware.nix, networking.nix) are imported automatically.
{
imports = [ inputs.imp.flakeModules.default ];
imp = {
src = ./outputs;
registry.src = [ ./mod ./hosts ./users ];
hosts.enable = true;
exports.enable = true;
};
}
Input collection
Declare flake inputs where they’re used:
# hosts/wsl/default.nix
{
__inputs.nixos-wsl.url = "github:nix-community/NixOS-WSL";
__host = {
system = "x86_64-linux";
modules = [ inputs.nixos-wsl.nixosModules.default ];
};
}
Run nix run .#imp-flake to regenerate flake.nix with collected inputs.