Files
gh-breakds-claude-bds-bds-dev/skills/nix-packaging/js/js.md
2025-11-29 18:02:30 +08:00

103 lines
3.1 KiB
Markdown

# 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](./claude-code/package.nix)
Key components:
- **Source**: Fetch from npm registry using `fetchzip` with URL pattern:
```nix
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 `postPatch` to copy a local `package-lock.json`:
```nix
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:
1. **Update package-lock.json**: Generate a new lock file for the target version:
```bash
# 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.json
```
**Note**: If `npm` is not installed, use `nix-shell` to run it:
```bash
nix-shell -p nodejs --run "npm i --package-lock-only @anthropic-ai/claude-code@\"$version\""
rm -f package.json
```
Copy the generated `package-lock.json` to your package directory.
2. **Update hashes**: Both `hash` (source) and `npmDepsHash` need updating.
**Method 1: Let Nix tell you**
- Set `hash = "";` and run `nix build`. Copy the correct hash from the error message.
- Set `npmDepsHash = "";` and run `nix build`. Copy the correct hash from the error message.
**Method 2: Calculate directly**
```bash
# 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>
```
3. **Check for breaking changes**: New versions may:
- Change build requirements (update `dontNpmBuild` or add build dependencies)
- Require different Node.js versions (update `nodejs` attribute, e.g., `nodejs_20`)
- Add new environment variables or runtime requirements
## Common Patterns
### Specify Node.js Version
For compatibility, especially on Darwin with sandboxed builds:
```nix
buildNpmPackage rec {
nodejs = nodejs_20;
# ...
}
```
### Disable Auto-Build
If the package is pre-built on the npm registry:
```nix
dontNpmBuild = true;
```
### Set Environment Variables
Use `postInstall` to wrap the binary with required environment variables:
```nix
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`.