Node.js Examples
These examples pin Node.js 22.14.0. Replace it deliberately when the project changes versions. No global Node.js installation is needed.
Select pnpm from package.json
No Starlark package-manager version is needed. Declare exact pnpm 11+ in project-root package.json:
{
"packageManager": "[email protected]"
}
Alternatively, request the newest stable release in a range:
{
"devEngines": {
"packageManager": {
"name": "pnpm",
"version": "^11.5.0",
"onFail": "download"
}
}
}
Loading @nodejs reads this declaration, ignores onFail, downloads and verifies the matching standalone pnpm GitHub archive, and shows download/install progress. Existing npm_install and npm_run calls then execute pnpm. Without either declaration, they continue to execute npm.
Managed pnpm is also available to general commands. xx runs pnpm config set --global globalBinDir <temporary-directory> against invocation-scoped config. Global packages and store data remain cached, while installed command shims are removed after the xx invocation. Commands propagate through task dependencies:
load("@[email protected]", "nodejs")
load("@os@1", "os_run")
install = os_run(
("pnpm", "install", "-g", "typescript"),
deps=[nodejs],
)
os_run(("tsc", "--version"), deps=[install])
Install and Build
Given project-root package.json and its npm build script:
load("@[email protected]", "npm_install", "npm_run")
install = npm_install()
npm_run("build", deps=[install])
The explicit dependency makes installation finish before the build. Without deps=[install], both commands are independent roots and may run concurrently.
Frozen Install and Test
Use frozen installation for a project with a committed, up-to-date lockfile:
load("@[email protected]", "npm_install", "npm_run")
install = npm_install(
frozen_lockfile=True,
audit=False,
)
npm_run("test", args=["--runInBand"], deps=[install])
With npm, this runs npm ci. With pnpm, this runs pnpm install --frozen-lockfile. Both require a matching lockfile. audit=False disables npm's audit network request and is ignored by pnpm. npm_run inserts -- before supplied script arguments.
Run Node.js Directly
load("@[email protected]", "nodejs")
load("@os@1", "os_run")
os_run(("node", "scripts/generate.mjs"), deps=[nodejs])
nodejs puts managed Node.js first in PATH for this command.
Run a Local npx Command
Install first when the command comes from project dependencies:
load("@[email protected]", "npm_install", "npx_run")
install = npm_install(frozen_lockfile=True)
npx_run("eslint", version="9.22.0", args=["."], deps=[install])
Run a Possibly Remote npx Command
load("@[email protected]", "npx_run")
npx_run("cowsay", version="1.6.0", args=["hello"])
npx may find a command locally or in its cache, or download it and prompt. This helper does not model npx-level options such as --yes; its command cannot begin with -. Use remote commands only after understanding their trust, prompt, cache, and network behavior.