Agent Skills: Packaging Binary Distributions for Nix

Best practices for packaging pre-compiled binaries (.deb, .rpm, .tar.gz, AppImage) for NixOS, handling library dependencies, or facing "library not found" errors with binary distributions

UncategorizedID: lihaoze123/my-skills/nix-packaging-best-practices

Install this agent skill to your local

pnpm dlx add-skill https://github.com/lihaoze123/my-claude-code/tree/HEAD/skills/nix-packaging-best-practices

Skill Files

Browse the full folder contents for nix-packaging-best-practices.

Download Skill

Loading file tree…

skills/nix-packaging-best-practices/SKILL.md

Skill Metadata

Name
nix-packaging-best-practices
Description
Best practices for packaging pre-compiled binaries (.deb, .rpm, .tar.gz, AppImage) for NixOS, handling library dependencies, or facing "library not found" errors with binary distributions

Packaging Binary Distributions for Nix

Extract and patch binary packages within Nix builds for reproducibility.

Core Principle

Source from original archive directly, never from pre-extracted directories.

When to Use

  • Converting binary packages (.deb, .rpm, .tar.gz, .zip) to Nix derivations
  • Packaging proprietary/closed-source software distributed as binaries
  • Electron/GUI apps show "library not found" errors
  • User provides pre-extracted binary contents
  • Binary distributions need library path fixes

Don't use for:

  • Software available in nixpkgs
  • Source-based packages (use standard derivation)
  • AppImages (use appimage-run or extract and patch)

Quick Reference

| Topic | Rule File | |-------|-----------| | Core pattern for .deb packages | essential-pattern | | .rpm, .tar.gz, .zip extraction | archive-formats | | nativeBuildInputs vs buildInputs | dependencies | | Local vs remote source files | source-files | | Common pitfalls and fixes | common-mistakes | | Finding missing libraries with ldd | finding-libraries | | Quick testing with steam-run | quick-testing | | Troubleshooting autoPatchelf errors | troubleshooting-autoPatchelf | | Version variable in filename | version-management | | Electron app dependencies | electron-apps | | FHS env for resistant binaries | advanced-fhs-env | | Build phases and hooks | build-phases | | Wrapper scripts with makeWrapper | wrapper-programs |

Essential Pattern (.deb)

{ pkgs }:

pkgs.stdenv.mkDerivation rec {
  pname = "appname";
  version = "1.0.0";

  src = ./AppName-${version}-linux-amd64.deb;

  nativeBuildInputs = with pkgs; [
    autoPatchelfHook  # Fixes library paths
    dpkg              # Extracts .deb
  ];

  buildInputs = with pkgs; [
    stdenv.cc.cc.lib
    glib
    gtk3
  ];

  unpackPhase = ''
    ar x $src
    tar xf data.tar.xz
  '';

  installPhase = ''
    mkdir -p $out
    cp -r opt/AppName/* $out/
  '';
}

Common Tasks

| Task | Solution | |------|----------| | Local archive | src = ./package-${version}.tar.gz | | Remote archive | src = fetchurl { url = "..."; hash = "sha256-..."; } | | Extract .deb | ar x $src && tar xf data.tar.xz + dpkg | | Extract .rpm | rpm2cpio $src \| cpio -idmv + rpm, cpio | | Extract .tar.gz | Auto-detected by stdenv | | Extract .zip | Add unzip to nativeBuildInputs | | Fix libraries | Add autoPatchelfHook to nativeBuildInputs | | Find missing libs | Run ldd result/bin/app for "not found" | | Quick test binary | nix-shell -p steam-run; steam-run ./binary | | Debug autoPatchelf | nix log /nix/store/...-drv | | Search libraries | nix-locate libX11.so.6 | | Wrapper scripts | Add makeWrapper to nativeBuildInputs | | Version sync | Use src = ./app-${version}.tar.gz |

Dependency Categories

nativeBuildInputs: Build-time tools (dpkg, autoPatchelfHook, makeWrapper) buildInputs: Runtime libraries (gtk3, glib, libpulseaudio) propagatedBuildInputs: Rarely needed for binary packaging

Common Library Mappings

| Missing Library | Nix Package | |-----------------|-------------| | libgtk-3.so.0 | gtk3 | | libglib-2.0.so.0 | glib | | libpulse.so.0 | libpulseaudio | | libGL.so.1 | mesa or libglvnd | | libxkbcommon.so.0 | libxkbcommon (NOT xorg.libxkbcommon) | | libstdc++.so.6 | stdenv.cc.cc.lib |

Red Flags - STOP

  • "User already extracted it, use that directory" → NO, source from original archive
  • "Absolute path works for me locally" → Breaks for others, use relative
  • "Just add more libraries until it works" → Find actual dependencies with ldd

How to Use

Read individual rule files for detailed explanations and code examples:

rules/essential-pattern.md
rules/archive-formats.md
rules/_sections.md

Each rule file contains:

  • Brief explanation of why it matters
  • Incorrect code example with explanation
  • Correct code example with explanation
  • Additional context and references

Full Compiled Document

For the complete guide with all rules expanded: AGENTS.md