bin-links: Package Binary Linker

6.0.0 · active · verified Sun Apr 19

bin-links is a fundamental JavaScript library within the npm ecosystem, responsible for linking package binaries and man pages. It handles the creation of symbolic links or shims for executable scripts defined in a package's `bin` field, directing them to appropriate locations like `node_modules/.bin` for local installs or global binary directories for global packages. It also manages linking man pages from the `man` field. The current stable version is v6.0.0, released in late 2025. This package generally follows the Node.js release cadence for its engine support, aligning with npm's own requirements. Its key differentiator is being a core, low-level utility maintained by the npm team, providing robust and cross-platform binary linking functionality crucial for package execution and discoverability in Node.js environments.

Common errors

Warnings

Install

Imports

Quickstart

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();

view raw JSON →