Like which(1) unix command - finds the first instance of an executable in the PATH.
npx @tessl/cli install tessl/npm-which@5.0.0Like the Unix which(1) command, this package finds the first instance of a specified executable in the PATH environment variable. It provides both asynchronous and synchronous APIs with comprehensive cross-platform support and does not cache results, making it ideal for dynamic environments where executables may be added or removed frequently.
npm install whichconst which = require('which');For ES modules (when using Node.js with ES module support):
import which from 'which';const which = require('which');
// Async usage - finds executable in PATH
try {
const resolved = await which('node');
console.log('Node.js found at:', resolved);
} catch (error) {
console.log('Node.js not found');
}
// Sync usage - finds executable in PATH
try {
const resolved = which.sync('node');
console.log('Node.js found at:', resolved);
} catch (error) {
console.log('Node.js not found');
}
// With nothrow option - returns null instead of throwing
const resolvedOrNull = await which('node', { nothrow: true });
if (resolvedOrNull) {
console.log('Found:', resolvedOrNull);
} else {
console.log('Not found');
}Asynchronously searches for executable in PATH environment variable.
/**
* Asynchronously find the first instance of an executable in PATH
* @param {string} cmd - Name of the executable to find
* @param {Object} [options] - Configuration options
* @param {string} [options.path] - Override PATH environment variable
* @param {string} [options.pathExt] - Override PATHEXT environment variable (Windows)
* @param {string} [options.delimiter] - Override path delimiter
* @param {boolean} [options.all=false] - Return all matches instead of just the first
* @param {boolean} [options.nothrow=false] - Return null instead of throwing when not found
* @returns {Promise<string|string[]|null>} Path to executable, array of paths (if all=true), or null (if nothrow=true and not found)
* @throws {Error} Error with code 'ENOENT' if executable not found (unless nothrow=true)
*/
function which(cmd, options);Synchronously searches for executable in PATH environment variable.
/**
* Synchronously find the first instance of an executable in PATH
* @param {string} cmd - Name of the executable to find
* @param {Object} [options] - Configuration options
* @param {string} [options.path] - Override PATH environment variable
* @param {string} [options.pathExt] - Override PATHEXT environment variable (Windows)
* @param {string} [options.delimiter] - Override path delimiter
* @param {boolean} [options.all=false] - Return all matches instead of just the first
* @param {boolean} [options.nothrow=false] - Return null instead of throwing when not found
* @returns {string|string[]|null} Path to executable, array of paths (if all=true), or null (if nothrow=true and not found)
* @throws {Error} Error with code 'ENOENT' if executable not found (unless nothrow=true)
*/
function whichSync(cmd, options);Command-line interface that mimics BSD which(1) behavior.
# Basic usage
node-which program1 program2 ...
# Find all matches
node-which -a program
# Silent mode (no output)
node-which -s program
# Combined flags
node-which -as program
# End of options
node-which program -- --anything-goes-hereCLI Options:
-a: Find all matches instead of just the first-s: Silent mode, suppress output--: End of options markerExit Codes:
0: Success (all requested executables found)1: Failure (one or more executables not found, or usage error)const which = require('which');
// Find all instances of an executable
const allPaths = await which('node', { all: true });
console.log('All node installations:', allPaths);
// Output: ['/usr/bin/node', '/usr/local/bin/node', ...]const which = require('which');
// Search in custom PATH
const customPath = '/custom/bin:/another/path';
const result = await which('myapp', {
path: customPath,
nothrow: true
});
if (result) {
console.log('Found myapp at:', result);
} else {
console.log('myapp not found in custom PATH');
}const which = require('which');
// Windows: search for executables with custom extensions
const result = await which('script', {
pathExt: '.js;.py;.bat',
nothrow: true
});const which = require('which');
// If command contains path separators, it's treated as a direct path
const absolutePath = await which('/usr/bin/node', { nothrow: true });
const relativePath = await which('./local-script.sh', { nothrow: true });The package throws structured errors when executables are not found:
const which = require('which');
try {
const result = await which('nonexistent-program');
} catch (error) {
console.log(error.message); // "not found: nonexistent-program"
console.log(error.code); // "ENOENT"
}
// Alternatively, use nothrow option
const result = await which('nonexistent-program', { nothrow: true });
if (result === null) {
console.log('Program not found');
}.EXE, .CMD, .BAT, .COM/**
* Configuration options for which function
*/
interface WhichOptions {
/** Override PATH environment variable */
path?: string;
/** Override PATHEXT environment variable (Windows only) */
pathExt?: string;
/** Override path delimiter (default: require('path').delimiter) */
delimiter?: string;
/** Return all matches instead of just the first (default: false) */
all?: boolean;
/** Return null instead of throwing when not found (default: false) */
nothrow?: boolean;
}
/**
* Error thrown when executable is not found
*/
interface WhichError extends Error {
/** Error message: "not found: <command>" */
message: string;
/** Error code: "ENOENT" */
code: 'ENOENT';
}