Command reference

#Run a tool

jup <binary>[@<version>] [...args]

Examples:

jup pnpm install
jup yarn@^4 --version
jup node@^22 script.js

A 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.

  • --here targets the current directory's manifest.
  • --no-integrity pins the version alone, and drops any digest already there.
  • --lock creates jup.lock when 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-directory uses exactly that writable directory.
  • --system uses the platform's system jup bin directory.
  • --all targets every supported tool, including the ones the default set leaves out.
  • --exclude removes a tool from the target set.
  • --force backs 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 0 when 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 install first.
  • 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 --version

jup --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 exit 1.
  • 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.

jup  Pin and run the right package manager or runtime for every project.