NIXTAMAL-MANIFEST(5)
πΈ NAME πΈ
Nixtamal Manifest(5) β setting up for pinning down inputs. No cap, that's the whole assignment. This page is lowkey the blueprint for how Nixtamal pins inputs, and we're gonna walk it together π
β¨ SYNOPSIS β¨
Okay so Nixtamal uses KDL for its manifest describing inputs. At the highest level, this includes:
- manifest version
- default hashing algorithm
patches(optional)- list of inputs
- the input kind & its specific attributes
- a command to check if βfreshβ
- hashing information
- patches to apply to the input
Note: A KDL Schema file is shipped alongside this documentation for use with schema-aware editors and validators. It can be found in the installation directory under share/nixtamal/manifest.kdl. Schema girlies stay winning.
π Default manifest.kdl π
Here's the default vibe, fr:
version "0.5.0"
inputs {
nixpkgs {
archive {
url "https://github.com/NixOS/nixpkgs/archive/{{fresh_value}}.tar.gz"
}
hash algorithm=SHA-256
fetch-time eval
fresh-cmd {
$ git ls-remote "https://github.com/NixOS/nixpkgs.git" --refs "refs/heads/nixos-unstable"
| cut -f1
}
}
}
π TOP-LEVEL NODES π
versionβ version of the Nixtamal spec themanifest.kdlis using. Iconic little version stamp.default-hash-algorithmβ hash algorithm to use by default for inputs when the input does not note its hash algorithm. Defaults toSHA-256.patchesβ map of patches to be applied to inputs where the patch name should be unique. Each patch has a URL (first argument). See Patches.default-fetch-timeβ default fetch time for inputs when not specified at the input level. Can beeval(fetch during Nix evaluation usingbuiltins.fetch*) orbuild(fetch during build usingpkgs.fetch*). Defaults toeval.default-gcβ EXPERIMENTAL: default garbage collection (GC) tracking behavior for inputs when not specified at the input level. Can betrackorskip(allow garbage collection). Defaults toskip. Experimental means bestie, read the label.inputsβ map of inputs to be pinned where the input+node name should be unique & will be used in the Nix output as well as logs & errors. See Input node.
π₯ FETCH TIME π₯
Inputs can be fetched either during Nix evaluation or during build time:
evalβ fetch the input during Nix evaluation usingbuiltins.fetch*functions. This is the default behavior and is suitable for inputs that need to be available during evaluation, such as the bootstrap Nixpkgs.buildβ fetch the input during build time usingpkgs.fetch*functions. This is suitable for most inputs and allows for better caching and parallel fetching.
The fetch time can be set globally using default-fetch-time or per-input using the fetch-time property on file, archive, and git input types.
Caution! Inputs with patches cannot use eval fetch time, as patches are applied during build time. The system will automatically enforce this constraint.
ποΈ GARBAGE COLLECTION ποΈ
The gc per-input property & document-level default-gc controls whether the input's Nix store path is protected from Nixtamal-controlled garbage collection by creating a silo GC root. The feature requires the NIXTAMAL_EXPERIMENTAL_GC environment variable. Silo GC root. Very mysterious. Very protected.
trackβ protect from garbage collection (whenNIXTAMAL_EXPERIMENTAL_GCis set).skipβ allow garbage collection (default).
π©Ή PATCHES π©Ή
Patches are defined at the top-level and can be applied to any input. This allows defining a patch once and applying it to multiple inputs. Reuse queen behavior.
prop: nameβ a string that specifies the path name in the Nix store. The Nix store has a very conservative set of values, narrower than ASCII, that are allowed as path which will definitely & unfortunately affect Unicode usage. Defaults to$NAME-patchif possible, otherwise warns for default behavior.prop: frozenβ a boolean (frozen=#true) that prevents trying refresh or otherwise get a new fresh value for this patch.prop: gcβ override the GC tracking behavior for this patch. Can betrackorskip. When absent, the value fromdefault-gcis used. See Garbage collection.urlβ templated node URL or file reference for the patch. Supportshttps://,http://, andfile://URLs.fresh-cmdβ command (with or without pipes using$&|nodes) that can be shelled out to return a string that will be locked as the fresh command value which can be used both to prevent unnecessary prefetching, but also for use in a Templated node.hashβ optional node for hash algorithm information. Thealgorithmproperty will be used when prefetching, locking, & for integrity verification. The optionalexpectedproperty may be used to assert a known hash. If not specified, no hash verification is performed. Defaults to the top-leveldefault-hash-algorithmorSHA-256.
π INPUT NODE π
At a high level these should be seen as:
prop: frozenβ a boolean (frozen=#true) that prevents trying refresh or otherwise get a new fresh value for this input.prop: gcβ override the GC tracking behavior for this input. Can betrackorskip. When absent, the value fromdefault-gcis used. See Garbage collection.prop: nameβ a string that specifies the path name in the Nix store. The Nix store has a very conservative set of values, narrower than ASCII, that are allowed as path which will definitely & unfortunately affect Unicode usage. Defaults to$NAME-srcif possible, otherwise warns for default behavior."kind"β there are specific nodes for each different type of supported fetchers/prefetchers:file,archive,git,darcs,pijul,fossil(with more to come in the future). Fetcher expansion pack loading.hashβ an optional node for hash algorithm information for an input. Thealgorithmproperty will be used when prefetching, locking, & for importing (which falls back to top-leveldefault-hash-algorithmor defined defaultSHA-256). The optionalexpectedproperty may be used to assert a known hash.
Caution! The bootstrapping Nixpkgs pin (either manually set or usingnixpkgs-nixtamalornixpkgsas defaults) must beSHA-256to be compatible withbuiltins.fetchTarball.
fresh-cmdβ command (with or without pipes using$&|nodes) that can be shelled out to return a string that will be locked as the fresh command value which can be used both to prevent unnecessary prefetching, but also for use in a Templated node.patchesβ list of patch names (as arguments) to apply to this input. Patches are defined at the top-level in the Patches section.
π File π
prop: fetch-timeβ property to set when to fetch this input:evalorbuild. Defaults to the top-leveldefault-fetch-timeorbuild.urlβ templated node URL reference for the input.mirrorsβ templated node URL mirror references for the input.
π¦ Archive π¦
prop: fetch-timeβ property to set when to fetch this input:evalorbuild. Defaults to the top-leveldefault-fetch-timeorbuild.urlβ templated node URL reference for the input.mirrorsβ templated node URL mirror references for the input.extensionβ annotation to helppkgs.fetchzipwith the correct extension type for the download (such as a/downloadURL that is a.tar.gz).
See: https://nixos.org/manual/nixpkgs/unstable/#sec-pkgs-fetchers-fetchzip Link drop, but make it documentation.
πΏ Git πΏ
prop: fetch-timeβ property to set when to fetch this input:evalorbuild. Defaults to the top-leveldefault-fetch-timeorbuild.repositoryβ templated node repository reference for the input.mirrorsβ templated node repository mirror references for the input.
Warning: Probably not yet supported upstream.
"reference"βbranchortagorrefnode as the reference point for getting stable reference.tagprovides convenience over usingrefwith full tag paths.submodulesβ leaf node for enabling submodules on a repository.lfsβ leaf node for enabling Git LFS on a repository.
π§Ά Darcs π§Ά
repositoryβ templated node repository reference for the input.mirrorsβ templated node repository mirror references for the input.
Note: Recently upstreamed. See: https://github.com/NixOS/nixpkgs/pull/467172
"reference"βcontextortagnode as the reference point for getting stable reference; in the case of Darcs, if neither is supplied a context will be assumed & copied fromnix-prefetch-darcs.
πͺΆ Pijul πͺΆ
remoteβ templated node remote reference for the input.mirrorsβ templated node remote mirror references for the input.
Note: Recently upstreamed. See: https://github.com/NixOS/nixpkgs/pull/467890
"reference"βchannelorstateorchange(not recommended) node as the reference point for getting stable reference; if unsure, trychannel main.
𦴠Fossil π¦΄
repositoryβ templated node repository reference for the input."reference"βbranchortagorcheck-innode as the reference point for getting stable reference.
π§ TEMPLATED NODE π§
Some nodes have values with string substitution via Jingoo https://tategakibunko.github.io/jingoo/templates/templates.en.html, which is probably overkill, but could give you flexibility with if statements. The templated nodes include:
inputs >> file > urlinputs >> file > mirrorsinputs >> archive > urlinputs >> archive > mirrorsinputs >> git > repositoryinputs >> git > mirrorsinputs >> darcs > repositoryinputs >> darcs > mirrorsinputs >> pijul > remoteinputs >> pijul > mirrorsinputs >> fossil > repositoryinputs >> fresh-cmd > $inputs >> fresh-cmd > |
The input kind affects the values for substitution:
okay so each of these input flavors has its own lil field list β and the types are doing so much work here, bestie ππ
πΎ file
nameβstringβ the input name, periodt.fresh_valueβstring nullableβ the fresh command return value.
π¦ archive
nameβstringβ the input name.fresh_valueβstring nullableβ the fresh command return value.
πΏ git
nameβstringβ the input name.fresh_valueβstring nullableβ the fresh command return value.branchβstring nullableβ branch name.refβstring nullableβ reference name.datetimeβstring nullableβ datetime of latest revision.lfsβboolβ repository uses LFS.submodulesβboolβ repository uses submodules.rev / revisionβstring nullableβ latest revision.
π darcs
nameβstringβ the input name.fresh_valueβstring nullableβ the fresh command return value.contextβstring nullableβ path to context file.tagβstring nullableβ tag.datetimeβstring nullableβ datetime of latest patch.weak_hashβstring nullableβ latest weak hash of the repository.
π§ pijul
nameβstringβ the input name.fresh_valueβstring nullableβ the fresh command return value.channelβstring nullableβ remote channel.changeβstring nullableβ change.datetimeβstring nullableβ datetime of latest patch.stateβstring nullableβ latest state of the remote or supplied state.
𦴠fossil
nameβstringβ the input name.fresh_valueβstring nullableβ the fresh command return value.branchβstring nullableβ branch name.tagβstring nullableβ tag.checkinβstring nullableβ check-in.dateβstring nullableβ date of latest patch.
π Input showcase π
Okay bestie, gather round β these are the little show-and-tell configs, and they are lowkey iconic. No cap, every snippet here is doing its own main-character thing. π«Ά
π Darcs using exposed WeakHash to avoid needless refresh
Hereβs the Darcs setup using an exposed WeakHash so it doesnβt do a needless refresh. The config is literally:
nixtamal {
darcs {
repository "https://darcs.toastal.in.th/nixtamal/stable/"
mirrors "https://smeder.ee/~toastal/nixtamal.darcs"
}
fresh-cmd {
$ curl -sL "https://darcs.toastal.in.th/nixtamal/stable/_darcs/weak_hash"
}
}
π Local directory checking for latest modification
Checking a local directory for the latest modification? This soupault-plugins moment is giving exactly that:
soupault-plugins {
file {
url "file:///home/toastal/my-project"
}
fresh-cmd {
$ find "/home/toastal/my-project" "-print0"
| xargs "-0" stat -c %Y
| sort -n
| tail -n1
}
}
π¦ Eval time file with mirror + templated nodes
This one is an eval-time file with a mirror plus templated nodes, and the {{fresh_value}} placeholder is serving in both URLs β obsessed:
mozilla-tls-guidelines {
file fetch-time=eval {
url "https://ssl-config.mozilla.org/guidelines/{{fresh_value}}.json"
mirrors "https://raw.githubusercontent.com/mozilla/ssl-config-generator/refs/tags/v{{fresh_value}}/src/static/guidelines/{{fresh_value}}.json"
}
fresh-cmd {
$ curl -sL "https://wiki.mozilla.org/Security/Server_Side_TLS"
| htmlq -w -t "table.wikitable:last-of-type > tbody > tr:nth-child(2) > td:first-child"
| head -n1
}
}
π Basic Pijul with BLAKE3 hash
Basic Pijul, but make it a BLAKE3 hash. The vibes are immaculate:
pijul {
pijul {
remote "https://nest.pijul.com/pijul/pijul"
channel main
}
hash algorithm=BLAKE3
}
π Inputs with patches
Patches are the main character here, fr fr. The patches block and the inputs block are literally this:
patches {
nixpkgs-pr123 "https://github.com/NixOS/nixpkgs/pull/123.diff"
my-fix "./patches/my-fix.patch"
}
inputs {
nixpkgs {
git {
repository "https://github.com/NixOS/nixpkgs.git"
ref "refs/heads/nixos-unstable"
}
patches "nixpkgs-pr123" "my-fix"
}
nixpkgs-stable {
git {
repository "https://github.com/NixOS/nixpkgs.git"
ref "refs/heads/nixos-24.05"
}
patches "my-fix"
}
}
Local patches (starting with ./ or ../) are applied directly from the repository and & be tracked by your VCS. βRemoteβ patches (meaning not local to the repository such as HTTPS, absolute paths with file:, & so forth) are fetched & hashed during nixtamal lock.
π Author π
toastal
Thatβs the whole page, bestie π The footer is serving version 1.4.0, source Nixtamal Manifest(5), and the date slot is empty (), so thatβs the tea. Byeee β¨π
π¦ where this page comes from
- nixpkgs unstable: ocaml5.5.1-nixtamal 2.4.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms