
# CI and offline use

jup can download a project's package manager before a build starts, then run entirely from its local cache. This makes package manager installation repeatable in CI, containers, and isolated environments.

## Cache the project package manager

Run this while the registry is available:

```sh
jup install
```

jup reads the current project pin and downloads that release without changing `package.json`.

To prove that later commands do not use the network:

```sh
JUP_ENABLE_NETWORK=0 pnpm install
```

A missing cache entry produces an error that names the required package manager and version.

## Use jup in CI

A typical CI job installs jup, warms its cache, and then disables network access for package manager resolution:

```sh
jup install
JUP_ENABLE_NETWORK=0 pnpm install --frozen-lockfile
```

Cache `JUP_HOME` between jobs if your CI service supports persistent caches. Run `jup info` to find its effective path.

If `packageManager` contains a range, commit `.corepack.lock`. When `CI` is set, jup refuses to create or update a range resolution by default. Refresh it locally with `jup up`, review the diff, and commit the result.

Set `JUP_FROZEN_LOCKFILE=0` only when a CI job is intentionally responsible for updating `.corepack.lock`.

## Build a container image

Copy the files that select the package manager before copying the rest of the project:

```dockerfile
COPY package.json ./
RUN jup install

ENV JUP_ENABLE_NETWORK=0
COPY . .
RUN pnpm install
```

For a range pin, include its resolution file in the first layer:

```dockerfile
COPY package.json .corepack.lock ./
RUN jup install
```

The package manager remains in a reusable image layer until the pin changes.

## Cache a specific release

To cache one release without changing a project pin or global fallback:

```sh
jup install -g --cache-only pnpm@11.1.2
```

Check the result with:

```sh
jup cache list
```

## Prepare an offline archive

On a connected machine, create an archive:

```sh
jup pack -o package-managers.tgz pnpm@11.1.2
```

Copy it to the isolated machine and import it:

```sh
jup install -g package-managers.tgz
jup cache list
```

`jup pack` also records the packed version as that manager's global fallback. A fallback applies only when a project has no package manager pin.

## Clear cached package managers

Remove downloaded versions while keeping global fallback records and cached signing keys:

```sh
jup cache clean
```

Remove downloaded versions and fallback records together:

```sh
jup cache clean --all
```

The next command that needs a removed release must download it again. For details about what jup checks before caching a download, read [Download verification](./security).
