Scripts
How pnpm handles the scripts field of package.json.
Hidden scripts#
Scripts with names starting with . are hidden. They cannot be run directly via pnpm run and are omitted from the pnpm run listing. Hidden scripts can only be called from other scripts.
{
"scripts": {
".helper": "echo 'I am hidden'",
"build": "pnpm run .helper && tsc"
}
}
In this example, pnpm run .helper would fail, but pnpm run build would succeed because .helper is called from another script.
Environment variables#
pnpm sets the following environment variables during lifecycle script execution:
npm_package_name: the package namenpm_package_version: the package versionnpm_package_config_*,npm_package_engines_*,npm_package_bin_*: theconfig,engines, andbinfields of the manifest, one variable per entry (for example,npm_package_config_port). A stringbinsetsnpm_package_bin.npm_package_json: the path to the package'spackage.jsonnpm_lifecycle_event: the name of the running script (e.g.,postinstall)npm_lifecycle_script: the command of the running scriptnpm_node_execpathandNODE: the path to the Node.js executablenpm_execpath: the path to the running pnpmnpm_config_user_agent: pnpm's user agent stringnpm_config_node_gyp: the path to the bundlednode-gyp, unless the environment already sets itINIT_CWD: the directory where pnpm was startedPNPM_SCRIPT_SRC_DIR: the directory of the package whose script runsTMPDIR:node_modules/.tmpin the package, unlessunsafePermistrue
Note
Apart from the variables above, pnpm does not set npm_config_* variables from
its configuration. Other npm_config_* variables in the environment reach the
script unchanged, except auth, scope-registry, and per-registry settings (names
starting with _, /, or @, or containing :_).
Processes a script leaves running#
A process that a script or a command run by pnpm exec or pnpm dlx starts
and leaves running, such as a daemon, an editor, or a browser opened by the
open package, keeps running after pnpm exits. It does so whether the script
succeeded or failed, and after Ctrl+C, just as it would if the script ran
without pnpm. Closing the terminal ends the processes attached to it, as the
operating system always does.
pnpm ends what it started in two cases only:
- When pnpm itself is killed or crashes while a script runs, for example when
a CI job is cancelled. On Windows this ends everything the script started,
except a process started with
CREATE_BREAKAWAY_FROM_JOB. On Unix it ends the scripts that run in a process group of their own, which is every script of a parallel run and every script started without a terminal. A process that leaves its process group, such as a daemon, keeps running. - When a script fails in a recursive or parallel run, pnpm stops the scripts
of the other packages that are still running, unless
--no-bailis set.
Built-in command and script name conflicts#
The following built-in commands prefer user scripts: clean (and its alias purge), setup, deploy, rebuild (and its alias rb), and tasks. If your package.json defines a script with one of these names, pnpm <name> will execute the script instead of the built-in command.
To force the built-in command, use pnpm pm <name>.
Lifecycle scripts#
pnpm install runs these scripts of each project in the workspace, in order:
preinstall, install, postinstall, preprepare, prepare, and
postprepare. With --prod, or when it installs specific packages, it runs
only preinstall, install, and postinstall.
For pre and post scripts of other scripts run by pnpm run,
see enablePrePostScripts.
pnpm:devPreinstall#
Runs when pnpm install runs in the project itself, including in CI. It does not run when the package is installed as a dependency of another project.
Runs before any dependency is installed.
This script is executed only when set in the root project's package.json.