Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
binLinks
✓ import binLinks from 'bin-links';
✗ const binLinks = require('bin-links');
While primarily a CommonJS module, it's designed to be imported as a default export in ES Modules. Using 'require' in an ESM context will throw a 'require is not defined' error.
binLinks.getPaths
✓ import binLinks from 'bin-links';
const paths = await binLinks.getPaths({ /* ... */ });
✗ import { getPaths } from 'bin-links';
'getPaths' is a method directly attached to the default 'binLinks' function/object, not a separate named export. Attempting a named import will result in 'getPaths is not exported from bin-links'.
binLinks.checkBins
✓ import binLinks from 'bin-links';
await binLinks.checkBins({ /* ... */ });
✗ import { checkBins } from 'bin-links';
'checkBins' is a method directly attached to the default 'binLinks' function/object, not a separate named export. Attempting a named import will result in 'checkBins is not exported from bin-links'.
This quickstart demonstrates how to use `bin-links` to create symbolic links for a package's binaries and man pages, simulating a local package installation. It shows the core `binLinks` function, along with `getPaths` and `checkBins` utility methods. The example includes directory setup and cleanup.
const binLinks = require('bin-links');
const path = require('path');
const fs = require('fs/promises');
// Simulate a package.json read for demonstration
async function readPackageJson(packagePath) {
try {
const pkgContent = await fs.readFile(packagePath, 'utf8');
return JSON.parse(pkgContent);
} catch (err) {
// Create a dummy package.json content if file not found
return {
name: 'some-package',
version: '1.0.0',
bin: {
'my-cli': 'cli.js'
},
man: [
'man/my-cli.1'
]
};
}
}
async function runBinLinkingExample() {
// Define paths relative to the current script execution
const tempDir = path.join(__dirname, 'temp-link-test');
const packageDir = path.join(tempDir, 'node_modules', 'some-package');
const binDir = path.join(tempDir, 'node_modules', '.bin');
const manDir = path.join(tempDir, 'share', 'man');
// Ensure necessary directories exist
await fs.mkdir(packageDir, { recursive: true });
await fs.mkdir(binDir, { recursive: true });
await fs.mkdir(path.join(packageDir, 'man'), { recursive: true });
await fs.mkdir(manDir, { recursive: true });
// Create dummy executable and man page files
await fs.writeFile(path.join(packageDir, 'cli.js'), '#!/usr/bin/env node\nconsole.log("Hello from my-cli!");', { mode: 0o755 });
await fs.writeFile(path.join(packageDir, 'man', 'my-cli.1'), '.TH "MY-CLI" "1" "2025-01-01" "1.0.0" "My CLI Manual"\n.SH NAME\nmy-cli - A sample command-line interface', { recursive: true });
const pkg = await readPackageJson(path.join(packageDir, 'package.json'));
console.log('Attempting to link binaries and man pages for ' + pkg.name + '...');
try {
await binLinks({
path: packageDir,
pkg: pkg,
global: false, // Set to true for global install simulation
top: true, // This is the top-level package being linked
force: true // Overwrite existing links if any
});
console.log('Binaries and man pages linked successfully!');
// Demonstrate checking for conflicts (should pass with force: true)
await binLinks.checkBins({
path: packageDir,
pkg: pkg,
global: false,
top: true,
force: true
});
console.log('No conflicting bins found (or forced overwrite).');
// List potential link paths (does not touch filesystem)
const potentialPaths = binLinks.getPaths({
path: packageDir,
pkg: pkg,
global: false,
top: true
});
console.log('Potential link paths:', potentialPaths);
} catch (error) {
console.error('Error during binary linking example:', error.message);
} finally {
// Clean up temporary directory after example
await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
console.log('Cleanup complete.');
}
}
runBinLinkingExample();
Errors
Common errors & fixes
Error: EACCES: permission denied, link '...' -> '...'
The Node.js process lacks the necessary file system permissions to create symbolic links or shims in the target directory.
fixEnsure the user running the Node.js process has write permissions to the destination directory (e.g., `node_modules/.bin` or global `bin` directory). On Unix-like systems, you might need to use `sudo` for global installations, though this is generally discouraged for local `npm install`.
TypeError: require is not a function
Attempting to use `require('bin-links')` in an ES Module context where CommonJS `require` is not natively available or polyfilled.
fixRefactor your import statement to use `import binLinks from 'bin-links';` to align with ESM syntax. Ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json`).
Error: The 'engines' field is not compatible with the current Node.js version.
The `bin-links` package specifies a strict Node.js engine range in its `package.json`, and your current Node.js version falls outside this range.
fixUpgrade your Node.js runtime to a version that satisfies the `engines.node` requirement specified in `bin-links`'s `package.json` (e.g., `^20.17.0 || >=22.9.0` for v6.0.0). Use a Node Version Manager (NVM) to switch to a compatible version.
Audit
Dependencies
read-cmd-shimrequiredUsed for reading command shims, essential for cross-platform binary linking.
write-file-atomicrequiredEnsures atomicity when writing files, preventing data corruption during link operations.
npm-normalize-package-binrequiredNormalizes and validates package `bin` field entries for consistent linking.
cmd-shimrequiredCreates Windows command shims for package binaries, ensuring executability.
proc-logrequiredProvides consistent logging capabilities for process events within the npm ecosystem.