Custom API
addAPI
Section titled “addAPI”.addAPI extends the import-tree object with new named methods. Each method receives the current import-tree instance (self) and can call any existing method on it.
import-tree.addAPI { helloOption = self: self.addPath ./modules/hello-option; feature = self: infix: self.filter (lib.hasInfix infix); minimal = self: self.feature "minimal";}After calling .addAPI, the new methods are available directly on the import-tree object:
extended.helloOption.filesextended.feature "networking" ./modulesextended.minimal ./srcPreserving Previous Extensions
Section titled “Preserving Previous Extensions”Calling .addAPI multiple times is cumulative — previous extensions are preserved:
let first = import-tree.addAPI { foo = self: self.addPath ./foo; }; second = first.addAPI { bar = self: self.addPath ./bar; };insecond.foo.files # still worksLate Binding
Section titled “Late Binding”API methods are late-bound. You can reference methods that don’t exist yet — they resolve when actually called:
let first = import-tree.addAPI { result = self: self.late; }; extended = first.addAPI { late = _self: "hello"; };inextended.result # => "hello"This enables building APIs incrementally across multiple .addAPI calls.
Real-World Example: Module Distribution
Section titled “Real-World Example: Module Distribution”A library author can ship a pre-configured import-tree with domain-specific methods:
# editor-distro flake module{ inputs, lib, ... }:let on = self: flag: self.filter (lib.hasInfix "+${flag}"); off = self: flag: self.filterNot (lib.hasInfix "+${flag}"); exclusive = self: onFlag: offFlag: (on self onFlag) |> (s: off s offFlag);in { flake.lib.modules-tree = lib.pipe inputs.import-tree [ (i: i.addPath ./modules) (i: i.addAPI { inherit on off exclusive; }) (i: i.addAPI { ruby = self: self.on "ruby"; }) (i: i.addAPI { python = self: self.on "python"; }) (i: i.addAPI { old-school = self: self.off "copilot"; }) (i: i.addAPI { vim-btw = self: self.exclusive "vim" "emacs"; }) ];}Consumers pick exactly the features they want:
# consumer flake module{ inputs, ... }:let ed = inputs.editor-distro.lib.modules-tree;in { imports = [ (ed.vim-btw.old-school.on "rust") ];}