New Pkg
Create a new Nix package derivation for existing software with automatic dependency detection and validation.
Claude CodeGeneric
# Package Existing Software for Nix
Create a new Nix package derivation for existing software with automatic dependency detection and validation.
## Quick Start
Just tell me:
1. **Software name** (e.g., "mycli", "awesome-tool")
2. **Source location** (GitHub URL, tarball URL, or "help me find it")
3. **Programming language** (C/C++, Python, Rust, Go, etc.)
I'll guide you through the rest interactively.
## What I'll Do
### 1. Research & Planning (Automatic)
- Analyze the software's build system (autoconf, cmake, meson, cargo, etc.)
- Identify likely dependencies from build files
- Determine appropriate fetcher (fetchFromGitHub, fetchurl, etc.)
- Check if package already exists in nixpkgs
### 2. Choose Package Location
**Options:**
- `pkgs/` directory in your project (recommended for custom packages)
- Overlay in `overlays/` (for extending nixpkgs)
- Standalone `default.nix` (for testing)
### 3. Create Package Derivation
Using this proven structure:
```nix
{ lib
, stdenv
, fetchFromGitHub
, # ... build dependencies
}:
stdenv.mkDerivation rec {
pname = "package-name";
version = "1.0.0";
src = fetchFromGitHub {
owner = "owner-name";
repo = "repo-name";
rev = "v${version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
nativeBuildInputs = [
# Build-time dependencies (compilers, build tools)
];
buildInputs = [
# Runtime dependencies (libraries)
];
# Custom build phases if needed
# configurePhase, buildPhase, installPhase
meta = with lib; {
description = "Short description";
homepage = "https://example.com";
license = licenses.mit;
maintainers = with maintainers; [ your-name ];
platforms = platforms.all;
mainProgram = "binary-name";
};
}
4. Hash Calculation (Automatic)
- Generate correct hash using
nix-prefetch-urlornix hash - Handle hash format conversion (sha256 to SRI format)
- Update derivation with correct hash
5. Dependency Detection (Interactive)
- Build the package and capture error messages
- Identify missing dependencies from build failures
- Search nixpkgs for required packages
- Add dependencies iteratively
6. Build Phase Customization (If Needed)
- Override phases for non-standard build systems
- Add custom install steps
- Handle special cases (no install target, custom paths)
7. Testing & Validation
- Build the package:
nix-build -A package-name - Test the binary:
./result/bin/program --version - Verify all dependencies are included
- Check for runtime errors
8. Integration
- Add to
pkgs/default.nixor overlay - Create usage example
- Document any special requirements
Packaging Workflow
Phase 1: Source Fetching
For GitHub repositories (recommended):
src = fetchFromGitHub {
owner = "username";
repo = "project";
rev = "v1.0.0"; # or git commit hash
hash = ""; # Leave empty initially
};
For release tarballs:
src = fetchurl {
url = "https://example.com/software-1.0.0.tar.gz";
hash = ""; # Leave empty initially
};
For other sources:
fetchgit- Git repositories (non-GitHub)fetchzip- ZIP archivesfetchPatch- Patches
Phase 2: Hash Generation
I'll automatically:
- Build with empty hash
- Extract correct hash from error message
- Convert to SRI format if needed
- Update derivation
Manual command:
nix-prefetch-url --unpack https://github.com/owner/repo/archive/v1.0.0.tar.gz
Phase 3: Dependency Discovery
Build and iterate:
- Run
nix-build - Read error messages for missing files/libraries
- Search nixpkgs:
nix search nixpkgs package-name - Add to
buildInputsornativeBuildInputs - Repeat until build succeeds
Common dependencies:
- C/C++:
pkg-config,cmake,autoconf,gcc,clang - Python:
python3,python3Packages.* - Rust:
cargo,rustc,rustPlatform.buildRustPackage - Go:
buildGoModule - Node:
nodejs,nodePackages.*
Phase 4: Build System Detection
I'll identify and configure:
Autotools (./configure && make):
nativeBuildInputs = [ pkg-config ];
configureFlags = [ "--enable-feature" ];
CMake:
nativeBuildInputs = [ cmake ];
cmakeFlags = [ "-DOPTION=ON" ];
Meson:
nativeBuildInputs = [ meson ninja ];
mesonFlags = [ "-Dfeature=enabled" ];
Make only:
makeFlags = [ "PREFIX=$(out)" ];
Custom build:
buildPhase = ''
runHook preBuild
./custom-build.sh
runHook postBuild
'';
Phase 5: Custom Installation
When software lacks standard install:
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp program $out/bin/
mkdir -p $out/share/doc/${pname}
cp README.md LICENSE $out/share/doc/${pname}/
runHook postInstall
'';
Common install patterns:
- Binaries →
$out/bin/ - Libraries →
$out/lib/ - Headers →
$out/include/ - Documentation →
$out/share/doc/ - Man pages →
$out/share/man/
Language-Specific Helpers
Rust Packages
{ rustPlatform, fetchFromGitHub }:
rustPlatform.buildRustPackage rec {
pname = "rust-tool";
version = "1.0.0";
src = fetchFromGitHub {
owner = "owner";
repo = "repo";
rev = "v${version}";
hash = "sha256-...";
};
cargoHash = "sha256-..."; # Run with empty string first
meta = { ... };
}
Python Packages
{ python3Packages, fetchPypi }:
python3Packages.buildPythonPackage rec {
pname = "python-package";
version = "1.0.0";
src = fetchPypi {
inherit pname version;
hash = "sha256-...";
};
propagatedBuildInputs = with python3Packages; [
requests
click
];
meta = { ... };
}
Go Packages
{ buildGoModule, fetchFromGitHub }:
buildGoModule rec {
pname = "go-tool";
version = "1.0.0";
src = fetchFromGitHub {
owner = "owner";
repo = "repo";
rev = "v${version}";
hash = "sha256-...";
};
vendorHash = "sha256-..."; # or null f
Maintain New Pkg?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[New Pkg on getagentictools](https://getagentictools.com/loops/olafkfreund-package-existing-software-for-nix?ref=badge)