Command reference
#Run a tool
jup <binary>[@<version>] [...args]Examples:
jup pnpm install
jup yarn@^4 --version
jup node@^22 script.jsA shim provides the shorter form (pnpm install). A one-command version
override still has to use the package manager required by a strict project.
#jup install
jup install [...args]Runs the install command of the package manager the current project pins, after
installing that manager if it is missing. jup install in a pnpm project is
pnpm install, without naming pnpm.
Arguments are passed straight through, so jup install --frozen-lockfile reaches
the manager as its own flag. The command writes nothing: no manifest, no
jup.lock, no global fallback. The version it runs is the one the project's pin
and jup.lock already select, so a warm project needs no network.
#jup run
jup run [...args]Runs a project script through the package manager the project pins: jup run build is pnpm run build in a pnpm project, yarn run build in a Yarn one, and
deno task build under Deno. A bare jup run lists the scripts, because that is
what a bare pnpm run does.
A command word jup does not recognize is a script name too, so jup lint runs
the lint script. Flags keep their error (jup --frobnicate), and so does
upgrade, which is reserved. Under the corepack name, an unrecognized command
stays an error.
Like jup install, it writes nothing and passes everything after the word
straight through.
#jup use
jup use [--here] [--no-integrity] [--lock] <name[@<version>]>Selects, verifies, and installs a tool, then writes the project pin. A typed
semver range stays in the manifest, and its selected release is recorded — in a
committed jup.lock where the project has one, and in the short-lived
node_modules/.jup cache where it does not. A bare name, tag, or exact version
writes an exact pin.
For package managers, use may then run the manager's install command. For a
runtime such as Node.js, it only writes devEngines.runtime.
--heretargets the current directory's manifest.--no-integritypins the version alone, and drops any digest already there.--lockcreatesjup.lockwhen the project has none. Only a range or tag pin records a release, so it does nothing for an exact pin.
#jup up
jup up [--here] [--no-integrity] [--lock]Updates the current project. For a range, it keeps the range and refreshes the
committed resolution in jup.lock where the project commits one; --lock
creates the file when it does not. For an exact pin, it chooses the newest
release in the same major line unless a structured project range allows another
line. Registry tags are not accepted by up.
#jup pack
jup pack [--json] [-o|--output <path>] [...name[@<version>]]Installs the selected versions, makes them global fallbacks on the source
machine, and writes complete store entries to an archive. The default output is
jup.tgz. --json prints the output path as JSON.
#Cache commands
jup cache install
jup cache install -g|--global [--cache-only] [...name[@<version>] | <file>.tgz]
jup cache list [--json]
jup cache clean [--all]
jup cache clear [--all]Bare install installs the version selected by the current project. It does not
edit the project, committed lockfile, or global fallback.
install -g installs named tools or imports portable jup archives. Without
--cache-only, each installed tool becomes the fallback outside pinned
projects.
list reports installed versions. clean and clear are aliases. They remove
installed tools; --all also removes recorded global defaults. They do not
remove jup's self-install or downloaded signing-key state.
#jup enable
jup enable [--install-directory <path>|--system] \
[--all] [--exclude <name>] [--force] [...name]Creates shims. With no names, it uses the built-in default set. A named tool expands to all binaries it provides.
--install-directoryuses exactly that writable directory.--systemuses the platform's system jup bin directory.--alltargets every supported tool, including the ones the default set leaves out.--excluderemoves a tool from the target set.--forcebacks up and replaces foreign entries.
--system and --install-directory cannot be combined, and neither can
--all and a list of names. --all --exclude <name> is fine.
#jup disable
jup disable [--install-directory <path>|--system] \
[--exclude <name>] [...name]Removes only entries owned by jup and restores anything that enable --force
backed up. With no names it considers every supported entry, including optional
shims. It does not remove foreign replacements.
#jup info
jup info [--json]
jup info --store-path [<name>]Builds an offline diagnostic report for the project, version resolution, store,
shims, .npmrc, TLS, and environment. Credential values are masked. The JSON
format has its own version; readers should ignore fields they do not know.
The report also lists the project inputs: every file discovery consults on its
way to deciding what a run installs — the manifest it selected, jup.lock, the
runtime's version file and the env file — as absolute paths, including the ones
that are not there. Build a CI cache key from that list rather than guessing at
it; see CI and offline use.
--store-path is the one form that is not the report. It prints where the
package manager keeps its own dependency store — the directory a CI job caches
next to JUP_HOME — as a single absolute path, and nothing else. With no name it
asks the project's manager; with one it asks that tool.
- It prints nothing and exits
0when the tool has no such command, is not installed, or answers nothing usable. Cache discovery is optional and must not fail a job. - It runs only what is already in the store: it resolves nothing and installs
nothing. Run
jup cache installfirst. - It cannot be combined with
--json. - An unknown name, or no name in a project that pins no package manager, is a usage error.
#Install jup itself
jup self-install [--install-directory <path>|--system] [--force]Copies the running jup installation to <JUP_HOME>/self/<version> and creates
jup and corepack entries. It does not use the network. The self copy is not
removed by cache clean.
jup self-upgrade [--install-directory <path>|--system] [--force]Downloads and verifies the latest published jup, installs it under self, and
updates the same entries. This is different from up, which updates the current
project's tool pin.
JUP_MINIMUM_RELEASE_AGE does not apply to jup's own release, and an upgrade
never goes backwards: if the registry's newest jup is older than the one running,
it says so and installs nothing.
#Help and version
jup --help
jup -h
jup help
jup --versionjup --version prints jup's version. jup pnpm --version runs pnpm and prints
pnpm's version.
#Exit and output behavior
- Successful jup commands exit
0; jup errors exit1. - A proxied tool's exit status or signal is preserved.
- Tool input and output pass through unchanged.
- Management logs and JSON go to stdout.
- Advisories, validation warnings, and download notices go to stderr.
- Proxy usage errors go to stderr. Management usage errors include the command's usage line on stdout.
Use NO_COLOR=1 to disable jup's own color. FORCE_COLOR forces it. jup never
adds styling to a proxied tool's output.