
Security News
OpenClaw Advisory Surge Highlights Gaps Between GHSA and CVE Tracking
A recent burst of security disclosures in the OpenClaw project is drawing attention to how vulnerability information flows across advisory and CVE systems.
@npmcli/run-script
Advanced tools
Run a lifecycle script for a package (descendant of npm-lifecycle)
const runScript = require('@npmcli/run-script')
runScript({
// required, the script to run
event: 'install',
// extra args to pass to the command, defaults to []
args: [],
// required, the folder where the package lives
path: '/path/to/package/folder',
// optional, these paths will be put at the beginning of `$PATH`, even
// after run-script adds the node_modules/.bin folder(s) from
// `process.cwd()`. This is for commands like `npm init`, `npm exec`,
// and `npx` to make sure manually installed packages come before
// anything that happens to be in the tree in `process.cwd()`.
binPaths: [
'/path/to/npx/node_modules/.bin',
'/path/to/npm/prefix/node_modules/.bin',
],
// optional, defaults to /bin/sh on unix, or cmd.exe on windows
scriptShell: '/bin/bash',
// optional, passed directly to `@npmcli/promise-spawn` which defaults it to true
// return stdout and stderr as strings rather than buffers
stdioString: false,
// optional, additional environment variables to add
// note that process.env IS inherited by default
// Always set:
// - npm_package_json The package.json file in the folder
// - npm_lifecycle_event The event that this is being run for
// - npm_lifecycle_script The script being run
// The fields described in https://github.com/npm/rfcs/pull/183
env: {
npm_package_from: 'foo@bar',
npm_package_resolved: 'https://registry.npmjs.org/foo/-/foo-1.2.3.tgz',
npm_package_integrity: 'sha512-foobarbaz',
},
// defaults to 'pipe'. Can also pass an array like you would to node's
// exec or spawn functions. Note that if it's anything other than
// 'pipe' then the stdout/stderr values on the result will be missing.
// npm cli sets this to 'inherit' for explicit run-scripts (test, etc.)
// but leaves it as 'pipe' for install scripts that run in parallel.
stdio: 'inherit',
// print the package id and script, and the command to be run, like:
// > somepackage@1.2.3 postinstall
// > make all-the-things
})
.then(({ code, signal, stdout, stderr, pkgid, path, event, script }) => {
// do something with the results
})
.catch(er => {
// command did not work.
// er is decorated with:
// - code
// - signal
// - stdout
// - stderr
// - path
// - pkgid (name@version string)
// - event
// - script
})
Call the exported runScript function with an options object.
Returns a promise that resolves to the result of the execution. Promise rejects if the execution fails (exits non-zero) or has any other error. Rejected errors are decorated with the same values as the result object.
If the stdio options mean that it'll have a piped stdin, then the stdin is ended immediately on the child process. If stdin is shared with the parent terminal, then it is up to the user to end it, of course.
code Process exit codesignal Process exit signalstdout stdout data (Buffer, or String when stdioString set to true)stderr stderr data (Buffer, or String when stdioString set to true)path Path to the package executing its scriptevent Lifecycle event being runscript Command being runIf stdio is inherit this package will emit a banner with the package
name and version, event name, and script command to be run, and send it
to proc-log.output.standard. Consuming
libraries can decide whether or not to display this.
path Required. The path to the package having its script run.event Required. The event being executed.args Optional, default []. Extra arguments to pass to the script.env Optional, object of fields to add to the environment of the
subprocess. Note that process.env IS inherited by default These are
always set:
npm_package_json The package.json file in the foldernpm_lifecycle_event The event that this is being run fornpm_lifecycle_script The script being runpackage.json fields described in
RFC183.scriptShell Optional, defaults to /bin/sh on Unix, defaults to
env.ComSpec or cmd on Windows. Custom script to use to execute the
command.stdio Optional, defaults to 'pipe'. The same as the stdio argument
passed to child_process functions in Node.js. Note that if a stdio
output is set to anything other than pipe, it will not be present in
the result/error object.cmd Optional. Override the script from the package.json with
something else, which will be run in an otherwise matching environment.stdioString Optional, passed directly to @npmcli/promise-spawn which
defaults it to true. Return string values for stderr and stdout rather
than Buffers.Note that this does not run pre-event and post-event scripts. The caller has to manage that process themselves.
This is an implementation to satisfy RFC 90, RFC 77, and RFC 73.
Apart from those behavior changes in npm v7, this is also just refresh of the codebase, with modern coding techniques and better test coverage.
Functionally, this means:
log.disableProgress() and log.enableProgress() at the appropriate
times, if necessary.)node executable is never added to the
PATH environment variable. (Ie, --scripts-prepend-node-path is
effectively always set to false.) Doing so causes more unintended side
effects than it ever prevented.cmd option pointing to the node_modules/.hook/${event}
script.In order to ensure that arguments are handled consistently, this module writes a temporary script file containing the command as it exists in the package.json, followed by the user supplied arguments having been escaped to ensure they are processed as literal strings. We then instruct the shell to execute the script file, and when the process exits we remove the temporary file.
In Windows, when the shell is cmd, and when the initial command in the script
is a known batch file (i.e. something.cmd) we double escape additional
arguments so that the shim scripts npm installs work correctly.
The actual implementation of the escaping is in lib/escape.js.
cross-env is a package that allows you to set environment variables across platforms before running scripts. It is similar to @npmcli/run-script in that it is often used in conjunction with npm scripts, but it focuses on environment variables rather than script execution itself.
npm-run-all is a CLI tool to run multiple npm-scripts in parallel or sequential. It provides a way to run scripts defined in package.json with more control over their execution order and concurrency, which is a different approach compared to the single script execution model of @npmcli/run-script.
shelljs is a portable Unix shell commands for Node.js. It allows you to execute shell commands programmatically, which can be used to run scripts or perform tasks similar to npm scripts. However, it is more general-purpose and not specifically tied to npm or package.json scripts.
FAQs
Run a lifecycle script for a package (descendant of npm-lifecycle)
The npm package @npmcli/run-script receives a total of 7,179,232 weekly downloads. As such, @npmcli/run-script popularity was classified as popular.
We found that @npmcli/run-script demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A recent burst of security disclosures in the OpenClaw project is drawing attention to how vulnerability information flows across advisory and CVE systems.

Research
/Security News
Mixed-script homoglyphs and a lookalike domain mimic imToken’s import flow to capture mnemonics and private keys.

Security News
Latio’s 2026 report recognizes Socket as a Supply Chain Innovator and highlights our work in 0-day malware detection, SCA, and auto-patching.