3.1 KiB
Package a JavaScript/TypeScript Application with Nix (npm)
Packaging an npm application (buildNpmPackage) involves determining the package name, version, and dependencies. The package must be available on the npm registry.
Normal npm Package
See the example: claude-code
Key components:
-
Source: Fetch from npm registry using
fetchzipwith URL pattern:url = "https://registry.npmjs.org/@scope/package-name/-/package-name-${version}.tgz";For non-scoped packages, omit the
@scope/part. -
Dependencies: Set
npmDepsHash(see update workflow below for obtaining the hash) -
package-lock.json: Use
postPatchto copy a localpackage-lock.json:postPatch = '' cp ${./package-lock.json} package-lock.json ''; -
Build control: Use
dontNpmBuild = true;if the package doesn't require a build step (already built on npm registry)
Updating an Existing npm Package
Besides the general update steps, also update npm-specific fields:
-
Update package-lock.json: Generate a new lock file for the target version:
# Find the latest version (or specific version) npm i --package-lock-only @anthropic-ai/claude-code@"$version" # Remove package.json (not needed for Nix packaging) rm -f package.jsonNote: If
npmis not installed, usenix-shellto run it:nix-shell -p nodejs --run "npm i --package-lock-only @anthropic-ai/claude-code@\"$version\"" rm -f package.jsonCopy the generated
package-lock.jsonto your package directory. -
Update hashes: Both
hash(source) andnpmDepsHashneed updating.Method 1: Let Nix tell you
- Set
hash = "";and runnix build. Copy the correct hash from the error message. - Set
npmDepsHash = "";and runnix build. Copy the correct hash from the error message.
Method 2: Calculate directly
# For source hash nix-prefetch-url --type sha256 --unpack https://registry.npmjs.org/@scope/package/-/package-${version}.tgz nix hash convert --hash-algo sha256 <old-hash> - Set
-
Check for breaking changes: New versions may:
- Change build requirements (update
dontNpmBuildor add build dependencies) - Require different Node.js versions (update
nodejsattribute, e.g.,nodejs_20) - Add new environment variables or runtime requirements
- Change build requirements (update
Common Patterns
Specify Node.js Version
For compatibility, especially on Darwin with sandboxed builds:
buildNpmPackage rec {
nodejs = nodejs_20;
# ...
}
Disable Auto-Build
If the package is pre-built on the npm registry:
dontNpmBuild = true;
Set Environment Variables
Use postInstall to wrap the binary with required environment variables:
postInstall = ''
wrapProgram $out/bin/your-binary \
--set ENV_VAR value \
--unset UNWANTED_VAR
'';
Handle Optional Dependencies
npm packages often have platform-specific optional dependencies (like Sharp's native bindings). These are automatically handled by buildNpmPackage based on the package-lock.json.