packaging
Skill1 starsChanged 9 months agoMITView on GitHub
corepkgs packaging conventions. Use when writing or reviewing any pkgs/<name>/default.nix — covers package organization (auto-registration, top-level.nix, alternative implementations), the finalAttrs pattern, meta attributes, where each kind of dependency belongs, fetchers, patching, install phases, multiple outputs, and passthru.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- lorena-bordonaba-pau/youtube-agenttheir own version, first seen Oct 13, 2026
- Build-Fractal/orchestratortheir own version, first seen Jun 2, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- lorena-bordonaba-pau/youtube-agent★ 2same name
- Build-Fractal/orchestrator★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- cmakeSkill
- ekala-cmake-nixSkill
- ekapkgs-repoSkill
- goSkill
- mesonSkill
- mk-many-variantsSkill
- nix-buildSkill
- nix-evalSkill
- portingSkill
- pythonSkill
- rustSkill
- structured-attrsSkill
- validationSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 13
Only when inputs deviate from those declared in the nix expression
- Very specific: line 26
Keep alternative implementations in the same package directory using multiple files: default.nix (short selector), generic.nix (usual …
- Very specific: line 29
Keep selection logic inside the package folder using ordinary if expressions and callPackage, forwarding explicit overrides.
- Very specific: line 41
Use finalAttrs pattern for self-referencing:
- Very specific: line 89
Goal: Keep builds as fast as possible by disabling in-build tests.
- Distinctive: line 123
Test configuration attributes are forwarded automatically:
- Very specific: line 130
When testPaths is not suitable (e.g., circular dependencies with pytest), create a separate tests.nix:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Packaging Conventions
Package Organization
Packages in pkgs/ and pkgs-many/ are automatically added to the pkgs.* scope based on their directory name. No explicit entry in top-level.nix is needed.
When to add an explicit top-level.nix entry:
- Only when inputs deviate from those declared in the nix expression
- Or when overriding default arguments / providing additional configuration
# top-level.nix — only if inputs deviate
libxslt = callPackage ./pkgs/libxslt {
pythonSupport = false;
cryptoSupport = true;
};Alternative Implementations
Keep alternative implementations in the same package directory using multiple files:
default.nix (short selector), generic.nix (usual implementation), darwin.nix (Apple's implementation).
Keep selection logic inside the package folder using ordinary if expressions and callPackage, forwarding explicit overrides. Avoid separate apple-<package> entries.
Expose libpcap.apple when callers need to choose an implementation. Preserve .override and .overrideAttrs on each implementation. For pkgs-many/ families, dispatch to separate implementation files from generic.nix. Use short variant names (real, darwin, v3_3); don't repeat the package name in package-local aliases.
Rules
- Never set
meta.maintainersormeta.teams— neither is a recognisedmetakey; setting one failscheck-meta. Simply omit them. __structuredAttrs = trueis the default — never set it explicitly. If phases break, fix them instead of disabling. See structured-attrs.doCheck = falseanddoInstallCheck = falseare defaults — don't set them explicitly. Usepassthru.testsfor test coverage.
Package Structure
Use finalAttrs pattern for self-referencing:
stdenv.mkDerivation (finalAttrs: {
pname = "example";
version = "1.0.0";
src = fetchFromGitHub {
owner = "example";
repo = "example";
tag = "v${finalAttrs.version}";
hash = "sha256-...";
};
passthru.tests = {
unittests = runUnitTests finalAttrs.finalPackage;
};
})Meta Attributes
Required fields:
meta = {
description = "Brief description";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
};Common licenses:
license = lib.licenses.mit;
license = lib.licenses.gpl3Plus;
license = with lib.licenses; [ gpl2Plus lgpl21Plus ];Platform options:
platforms = lib.platforms.linux; # Linux only
platforms = lib.platforms.unix; # Unix-like
platforms = lib.platforms.darwin; # macOS only
platforms = lib.platforms.all; # All platformsTesting
Goal: Keep builds as fast as possible by disabling in-build tests. Use passthru.tests to preserve test coverage without slowing every build.
Defaults
doCheck = false; and doInstallCheck = false; are the defaults across all build systems (stdenv.mkDerivation, buildPythonPackage, buildRustPackage, buildGoModule, buildPerlPackage). Don't set them explicitly.
Auto-Generated passthru.tests.build
buildRustPackage and buildGoModule automatically provide passthru.tests.build — a variant that re-runs the build with doCheck = true. User-supplied passthru.tests entries are merged alongside, not replaced.
For stdenv.mkDerivation packages, add passthru.tests manually:
passthru.tests = {
withChecks = finalAttrs.finalPackage.overrideAttrs { doCheck = true; };
};Python: testPaths (Preferred)
Set testPaths to auto-generate passthru.tests.python and a test_src output:
nativeCheckInputs = [ pytestCheckHook ];
testPaths = [ "tests" ];The test_src output bundles the listed paths plus config files (conftest.py, pyproject.toml, etc.). A standalone test derivation runs the suite against the installed package.
For suites that need extra files (helper modules, fixture data):
testPaths = [ "tests" "src/helpers" "README.rst" ];Test configuration attributes are forwarded automatically:
disabledTests,disabledTestPaths,enabledTestPathspytestFlags,pytestFlagsArray,unittestFlagsArraypreCheck,postCheck,preInstallCheck,postInstallCheck
Python: Manual tests.nix (Fallback)
When testPaths is not suitable (e.g., circular dependencies with pytest), create a separate tests.nix:
# default.nix
passthru.tests = {
pytest = callPackage ./tests.nix { };
};Acceptable In-Build Checks
doInstallCheck = true; is acceptable for:
versionCheckHook— verifies the built binary runs and prints expected versionpythonImportsCheck— runs automatically inbuildPythonPackage, no need to enable explicitly
Dependencies
nativeBuildInputs = [ # Build tools (build platform)
pkg-config
cmake
];
buildInputs = [ # Libraries (host platform)
zlib
openssl
];
checkInputs = [ # Test dependencies
pytest
];
propagatedBuildInputs = [ # Runtime deps for dependents
python3
];Cross-compilation:
strictDeps = true;
depsBuildBuild = [ pkg-config ]; # Build -> build tools
nativeBuildInputs = [ cmake ]; # Build -> host tools
buildInputs = [ zlib ]; # Host librariesFetching Sources
GitHub:
src = fetchFromGitHub {
owner = "example";
repo = "example";
tag = "v${finalAttrs.version}";
hash = "sha256-...";
};GitLab:
src = fetchFromGitLab {
domain = "gitlab.com";
owner = "example";
repo = "example";
tag = finalAttrs.version;
hash = "sha256-...";
};Tarball:
src = fetchurl {
url = "https://example.com/releases/example-${finalAttrs.version}.tar.gz";
hash = "sha256-...";
};Patching
Substitutions:
postPatch = ''
substituteInPlace Makefile \
--replace '/usr/local' "$out" \
--replace 'python' '${python3}/bin/python3'
'';Patch files:
patches = [
./fix-build.patch
(fetchpatch {
url = "https://github.com/example/example/commit/abc123.patch";
hash = "sha256-...";
})
];Install Phase
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp example $out/bin/
runHook postInstall
'';Post-install fixups:
postInstall = ''
wrapProgram $out/bin/example \
--prefix PATH : ${lib.makeBinPath [ coreutils ]}
'';Multiple Outputs
outputs = [ "out" "dev" "doc" ];
postInstall = ''
moveToOutput include $dev
moveToOutput share/doc $doc
'';Passthru
passthru = {
tests = {
unittests = runUnitTests finalAttrs.finalPackage;
};
plugins = {
foo = callPackage ./plugins/foo.nix { };
};
};Porting from nixpkgs
Remove:
updateScriptfrom passthru- Maintainers list (set to
[ ]) - nixpkgs-specific test infrastructure
Add TODO for missing deps:
buildInputs = [
zlib
# TODO(corepkgs): Port openssl for TLS support
];Complete Example
{
lib,
stdenv,
fetchFromGitHub,
cmake,
pkg-config,
zlib,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "example";
version = "2.1.0";
src = fetchFromGitHub {
owner = "example-org";
repo = "example";
tag = "v${finalAttrs.version}";
hash = "sha256-...";
};
nativeBuildInputs = [
cmake
cmake.configurePhaseHook
pkg-config
];
buildInputs = [ zlib ];
strictDeps = true;
cmakeBuildType = "Release";
passthru.tests = {
unittests = runUnitTests finalAttrs.finalPackage;
};
meta = {
description = "Example library";
homepage = "https://github.com/example-org/example";
license = lib.licenses.mit;
platforms = lib.platforms.unix;
};
})Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

