Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API Methods

imp.filter

Filter paths by predicate. Multiple filters compose with AND.

Example

imp.filter (lib.hasInfix "/services/") ./modules
imp.filterNot (lib.hasInfix "/deprecated/") ./modules

Arguments

predicate : Function that receives a path string and returns boolean.

imp.filterNot

Exclude paths matching predicate. Opposite of filter.

Example

imp.filterNot (lib.hasInfix "/deprecated/") ./modules

Arguments

predicate : Function that receives a path string and returns boolean.

imp.match

Filter paths by regex. Uses builtins.match.

Example

imp.match ".*[/]services[/].*" ./nix

Arguments

regex : Regular expression string.

imp.matchNot

Exclude paths matching regex. Opposite of match.

Example

imp.matchNot ".*[/]test[/].*" ./src

Arguments

regex : Regular expression string.

imp.initFilter

Replace the default filter. By default, imp finds .nix files and excludes paths containing underscore prefixes.

Example

# Import markdown files instead of nix files
imp.initFilter (lib.hasSuffix ".md") ./docs

Arguments

predicate : Function that receives a path string and returns boolean.

imp.map

Transform each matched path. Composes with multiple calls.

Example

imp.map import ./packages

Arguments

f : Transformation function applied to each path or value.

imp.mapTree

Transform values when building a tree with .tree. Composes with multiple calls.

Example

(imp.withLib lib)
  .mapTree (drv: drv // { meta.priority = 5; })
  .tree ./packages

Arguments

f : Transformation function applied to each tree value.

imp.withLib

Provide nixpkgs lib. Required before using .leafs, .files, .tree, or .configTree.

Example

imp.withLib pkgs.lib
imp.withLib inputs.nixpkgs.lib

Arguments

lib : The nixpkgs lib attribute set.

imp.addPath

Add additional paths to search.

Example

(imp.withLib lib)
  .addPath ./modules
  .addPath ./vendor
  .leafs

Arguments

path : Path to add to the search.

imp.addAPI

Extend imp with custom methods. Methods receive self for chaining.

Example

let
  myImp = imp.addAPI {
    services = self: self.filter (lib.hasInfix "/services/");
    packages = self: self.filter (lib.hasInfix "/packages/");
  };
in
myImp.services ./nix

Arguments

api : Attribute set of name = self: ... methods.

imp.pipeTo

Apply a function to the final file list.

Example

(imp.withLib lib).pipeTo builtins.length ./modules

Arguments

f : Function to apply to the file list.

imp.leafs

Get the list of matched files. Requires .withLib.

Example

(imp.withLib lib).leafs ./modules

imp.tree

Build a nested attrset from directory structure. Requires .withLib.

Directory names become attribute names. Files are imported and their values placed at the corresponding path.

Example

(imp.withLib lib).tree ./outputs
# { packages.hello = <imported>; apps.run = <imported>; }

Arguments

path : Root directory to build tree from.

imp.treeWith

Convenience function combining .withLib, .mapTree, and .tree.

Example

# These are equivalent:
((imp.withLib lib).mapTree (f: f args)).tree ./outputs
imp.treeWith lib (f: f args) ./outputs

Arguments

lib : The nixpkgs lib attribute set.

f : Transformation function for tree values.

path : Root directory to build tree from.

imp.configTree

Build a module where directory structure maps to NixOS option paths. Each file receives module args and returns config values.

Example

{ inputs, lib, ... }: {
  imports = [ ((inputs.imp.withLib lib).configTree ./config) ];
}
# File ./config/programs/git.nix sets config.programs.git

Arguments

path : Root directory containing config files.

imp.configTreeWith

Like .configTree but passes extra arguments to each file.

Example

(imp.withLib lib).configTreeWith { myArg = "value"; } ./config

Arguments

extraArgs : Additional arguments passed to each config file.

path : Root directory containing config files.

imp.mergeConfigTrees

Merge multiple config trees into a single module.

Example

# Later trees override earlier (default)
(imp.withLib lib).mergeConfigTrees [ ./base ./overrides ]

# With mkMerge semantics
(imp.withLib lib).mergeConfigTrees { strategy = "merge"; } [ ./base ./local ]

Arguments

options (optional) : Attribute set with strategy ("override" or "merge") and extraArgs.

paths : List of directories to merge.

imp.new

Returns a fresh imp instance with empty state, preserving custom API extensions.

Example

let
  customImp = imp.addAPI { myMethod = self: self.filter predicate; };
  fresh = customImp.new;
in
fresh.myMethod ./src

imp.imports

Build a modules list from mixed items. Handles paths, registry nodes, and modules.

For registry nodes or paths that import to attrsets with __module, extracts just the __module. For functions that are "registry wrappers" (take inputs arg and return attrsets with __module), wraps them to extract __module from the result.

This allows registry modules to declare __inputs and __overlays without polluting the module system.

Example

modules = imp.imports [
  registry.hosts.server
  registry.modules.nixos.base
  ./local-module.nix
  inputs.home-manager.nixosModules.home-manager
  { services.openssh.enable = true; }
];

Arguments

items : List of paths, registry nodes, or module values.

imp.analyze

Namespace for dependency analysis and visualization.

Example

graph = (imp.withLib lib).analyze.registry { registry = myRegistry; }
html = (imp.withLib lib).analyze.toHtml graph
json = (imp.withLib lib).analyze.toJson graph

imp.fragments

Collect fragments from a .d directory. Requires .withLib.

Follows the .d convention where fragments are sorted by filename and composed together. Files are processed in order (00-base before 10-extra).

Returns an attrset with multiple access methods:

  • .list - raw list of fragment contents
  • .asString - fragments concatenated with newlines (for shell scripts)
  • .asList - fragments flattened (for lists of packages)
  • .asAttrs - fragments merged (for attrsets)

Note: For known flake output directories (packages.d, devShells.d, etc.), tree.nix auto-merges fragments. Use imp.fragments for other .d dirs like shellHook.d or shell-packages.d.

Example

let
  imp = inputs.imp.withLib lib;

  # Shell scripts concatenated
  shellHookFragments = imp.fragments ./shellHook.d;

  # Package lists merged
  shellPkgFragments = imp.fragmentsWith { inherit pkgs self'; } ./shell-packages.d;
in
pkgs.mkShell {
  packages = shellPkgFragments.asList;
  shellHook = shellHookFragments.asString;
}

Arguments

dir : Directory ending in .d containing fragments (.nix or .sh files).

imp.fragmentsWith

Collect fragments with arguments passed to each .nix file.

Like fragments, but calls each .nix fragment as a function with the provided arguments. Shell (.sh) files are still read as strings.

Example

# Each file in shell-packages.d/ is called with { pkgs, self' }
# and should return a list like [ pkgs.ast-grep self'.packages.lint ]
shellPkgs = (imp.withLib lib).fragmentsWith { inherit pkgs self'; } ./shell-packages.d;
packages = shellPkgs.asList;

Arguments

args : Attrset of arguments to pass to each fragment function.

dir : Directory containing fragments.

Registry

imp.buildRegistry

Build registry from a directory. Each directory gets __path plus child entries.

Arguments

root : Root directory path to scan.

imp.flattenRegistry

Flatten registry to dot-notation paths.

flattenRegistry registry
# => { home.alice = <path>; modules.nixos.base = <path>; }

registry

: Function argument

imp.lookup

Lookup a dotted path in the registry.

lookup "home.alice" registry  # => <path>

path

: Function argument

registry

: Function argument

imp.makeResolver

Create resolver function: name -> path.

resolve = makeResolver registry;
resolve "home.alice"  # => <path>

registry

: Function argument

imp.toPath

Extract path from registry value. Works for paths and __path nodes.

x

: Function argument

imp.isRegistryNode

Check if a value is a registry node (has __path).

x

: Function argument

Format Flake

imp.formatValue

Format a value as Nix source code.

Arguments

depth : Indentation depth level.

value : Value to format (string, bool, int, null, list, or attrset).

imp.formatInput

Format a single input definition (at depth 1).

Arguments

name : Input name.

def : Input definition attrset.

imp.formatInputs

Format multiple inputs as a block.

Example

formatInputs { treefmt-nix = { url = "github:numtide/treefmt-nix"; }; }
# => "treefmt-nix.url = \"github:numtide/treefmt-nix\";"

Arguments

inputs : Attrset of input definitions.

imp.formatFlake

Generate complete flake.nix content.

Example

formatFlake {
  description = "My flake";
  coreInputs = { nixpkgs.url = "github:nixos/nixpkgs"; };
  collectedInputs = { treefmt-nix.url = "github:numtide/treefmt-nix"; };
}

Arguments

description : Flake description string (optional).

coreInputs : Core flake inputs attrset (optional).

collectedInputs : Collected inputs from __inputs declarations (optional).

outputsFile : Path to outputs file (default: "./outputs.nix").

header : Header comment for generated file (optional).

Analyze

imp.analyzeConfigTree

Analyze a single configTree, returning nodes and edges.

The path should be a directory. We scan it for .nix files and read each one to check for registry references.

Note: We only collect refs from files directly in this directory, not from subdirectories (those are handled as separate nodes).

Arguments

path : Directory path to analyze.

id : Identifier for this config tree node.

imp.analyzeMerge

Analyze a mergeConfigTrees call.

Arguments

id : Identifier for this merged tree.

sources : List of { id, path } for each source tree.

strategy : Merge strategy ("merge" or "override").

imp.analyzeRegistry

Analyze an entire registry, discovering all modules and their relationships.

This walks the registry structure, finds all configTrees, and analyzes each one for cross-references. Optionally also scans an outputs directory to include flake outputs (like nixosConfigurations) as sink nodes.

Example

analyzeRegistry { registry = myRegistry; }
# => { nodes = [...]; edges = [...]; }

# With outputs directory
analyzeRegistry { registry = myRegistry; outputsSrc = ./outputs; }

Arguments

registry : Registry attrset to analyze.

outputsSrc : Optional path to outputs directory (e.g., imp.src). Files here that reference registry paths will be included as output nodes.

imp.scanDir

Scan a directory and build a list of all .nix files with their logical paths.

Example

scanDir ./nix
# => [ { path = /abs/path.nix; segments = ["programs" "git"]; } ... ]

Arguments

root : Root directory to scan.

Visualize

imp.toJson

Convert graph to a JSON-serializable structure with full paths.

Arguments

graph : Graph with nodes and edges from analyze functions.

imp.toJsonMinimal

Convert graph to JSON without paths (avoids store path issues with special chars).

Arguments

graph : Graph with nodes and edges from analyze functions.

Export Sinks

imp.collectExports

Scan directories for __exports declarations and collect them.

Recursively scans .nix files for __exports attribute declarations and collects them, tracking source paths. Returns an attrset mapping sink keys to lists of export records.

Only attrsets with __exports are collected. For functions that need to declare exports, use the __functor pattern:

{
  __exports."nixos.role.desktop" = {
    value = { services.pipewire.enable = true; };
    strategy = "merge";
  };
  __functor = _: { inputs, ... }: { __module = ...; };
}

Example

imp.collectExports ./registry
# => {
#   "nixos.role.desktop" = [
#     {
#       source = "/path/to/audio.nix";
#       value = { services.pipewire.enable = true; };
#       strategy = "merge";
#     }
#   ];
# }

Arguments

pathOrPaths : Directory/file path, or list of paths, to scan for __exports declarations.

imp.buildExportSinks

Build export sinks from collected exports.

Takes collected exports and merges them according to their strategies, producing a nested attrset of sinks. Each sink contains merged values and metadata about contributors.

Example

buildExportSinks {
  lib = nixpkgs.lib;
  collected = imp.collectExports ./registry;
  sinkDefaults = {
    "nixos.*" = "merge";
    "hm.*" = "merge";
  };
}
# => {
#   nixos.role.desktop = {
#     __module = { ... };
#     __meta = { contributors = [...]; strategy = "merge"; };
#   };
# }

Arguments

lib : nixpkgs lib for merge operations.

collected : Output from collectExports.

sinkDefaults : Optional attrset mapping glob patterns to default strategies.

enableDebug : Include __meta with contributor info (default: true).

Standalone Utilities

imp.collectInputs

Scan directories for __inputs declarations and collect them.

Recursively scans .nix files for __inputs attribute declarations and merges them into a single attrset. Detects conflicts when the same input name has different definitions in different files.

Only attrsets with __inputs are collected. For files that need to be functions (e.g., to receive inputs at runtime), use the __functor pattern so __inputs is accessible without calling the function:

{
  __inputs.foo.url = "github:foo/bar";
  __functor = _: { inputs, ... }: inputs.foo.lib.something;
}

Accepts either a single path or a list of paths. When given multiple paths, all are scanned and merged with conflict detection.

Example

# Single path
imp.collectInputs ./outputs
# => { treefmt-nix = { url = "github:numtide/treefmt-nix"; }; }

# Multiple paths
imp.collectInputs [ ./outputs ./registry ]
# => { treefmt-nix = { ... }; nur = { ... }; }

Arguments

pathOrPaths : Directory/file path, or list of paths, to scan for __inputs declarations.

imp.collectAndFormatFlake

Convenience function combining collectInputs and formatFlake.

Scans a directory for __inputs declarations and generates complete flake.nix content in one step.

Example

imp.collectAndFormatFlake {
  src = ./outputs;
  coreInputs = { nixpkgs.url = "github:nixos/nixpkgs"; };
  description = "My flake";
}
# => "{ description = \"My flake\"; inputs = { ... }; ... }"

Arguments

src : Directory to scan for __inputs declarations.

coreInputs : Core flake inputs attrset (optional).

description : Flake description string (optional).

outputsFile : Path to outputs file (default: "./outputs.nix").

header : Header comment for generated file (optional).