Pin and run the right package manager or runtime for every project.
jup (can be pronounced “yup” too!) manages versions of package managers and runtimes. It is fast, small, and has no dependencies. It supports npm, pnpm, Yarn, aube, upm, vlt, Bun, Deno, nub, and Node.js.
Each project can choose a version. jup downloads and checks that version, saves it on your computer, and runs it. After the exact version is installed, jup can run it without an internet connection.
Warning
jup is experimental. Its behavior may change between releases.
curl -fsSL https://jup.unjs.io/install.sh | shOn Windows:
irm https://jup.unjs.io/install.ps1 | iexWith an existing Node.js installation:
npx jup self-installjup enableThis creates shims so commands such as pnpm, yarn, and npm pass through
jup.
From your project directory:
jup use pnpm@^12This keeps the range in package.json. To also record the selected release in a
committed jup.lock:
jup use --lock pnpm@^12Without a project jup.lock, each checkout chooses a matching release
independently. When node_modules already exists, jup may reuse that registry
answer for 24 hours from the disposable node_modules/.jup/jup.lock cache.
Then keep using the normal command:
pnpm install
pnpm --versionWithout shims, put jup before the tool command:
jup pnpm install
jup node@^22 script.jsjup install runs the install command of whichever manager the project pins, so
a script does not have to name it. jup run does the same for project scripts,
and a word jup does not recognize is a script name:
jup install
jup install --frozen-lockfile
jup run build
jup lintRun jup info at any time to inspect the selected project, version, local store,
network settings, and shims.
Read the complete getting-started guide →
setup-jup reads your project pins, installs the tools, restores their caches,
and installs dependencies.
- uses: actions/checkout@v6
- uses: unjs/setup-jup@85aa1e9e4cd2995fba3bee414cde74bf88637a2c # v1.0.0
- run: pnpm testSee inputs, outputs, and examples →
- One version for the whole team. The project records the tool it needs.
- Normal commands. Keep typing
pnpm,yarn, ornpmafter enabling shims. - Checked downloads. Artifacts are checked against pinned digests or trusted registry metadata before installation.
- Useful offline behavior. Already-installed exact versions run without a registry request.
- Reproducible ranges. Keep a range in the project and commit its selected
version in
jup.lock. - No plugins or telemetry. The supported tool table is built into jup.
flowchart LR
command["pnpm install"] --> project["Read the project"]
project --> select["Select a version"]
select --> cached{"Already installed?"}
cached -- Yes --> run["Run pnpm"]
cached -- No --> verify["Download and verify"]
verify --> run
jup passes arguments, input, output, exit codes, and signals through to the
selected tool. It manages the tool itself, not your project dependencies:
pnpm install still installs those dependencies.
Package-manager pins live in devEngines.packageManager in package.json.
Node.js pins live in devEngines.runtime; jup can also read .nvmrc. Existing
top-level packageManager pins remain supported.
- Get started
- Projects, pins, ranges, and workspaces
- GitHub Actions
- CI, containers, and offline installs
- Registries, authentication, TLS, and proxies
- Command reference
- Integrity and security model
- Environment and settings
- Moving from Corepack
- Troubleshooting
- Programmatic API
jup provides a corepack command and supports existing Corepack project pins and
workflows. New package-manager pins are written to devEngines.packageManager,
which Corepack itself does not read.
jup builds on the work of Corepack and its contributors. Its compatibility behavior is modeled on Corepack v0.35.0.
Published under the MIT License.
Portions derived from Corepack, Copyright © Corepack contributors, are also MIT licensed. See LICENSE for the full notice.