# lpm upgrade (/docs/packages/upgrade)



```bash
lpm upgrade [package...]
```

Walks `package.json` `dependencies` and `devDependencies`, looks up the newest installable version for each eligible package, and updates the lockfile + `node_modules` accordingly. By default it stays within your declared semver — pass `--major` to bump across breaking-change boundaries.

**Default scope: `@lpm.dev/*` plus npm packages already recorded as public npm or LPM.dev Registry-proxy installs in `lpm.lock`.** That means a normal `react`, `lodash`, or `@scope/pkg` install that currently resolves through `registry.npmjs.org` or the configured LPM.dev Registry proxy is eligible for `lpm upgrade` too. Packages without recorded public npm or LPM.dev Registry-proxy source attribution are skipped by unscoped `lpm upgrade` instead of being queried against `registry.npmjs.org` — this avoids leaking private/custom-registry package names. If you added a public npm package before LPM CLI recorded source metadata, run [`lpm install`](/docs/packages/install) once to refresh `lpm.lock`, then rerun `lpm upgrade`.

Pass package names to target only those direct manifest dependencies:

```bash
lpm upgrade zod
lpm upgrade zod react --dry-run --json
```

Targeted upgrade filters candidates before metadata fetch. In a TTY, the multiselect only shows the requested packages; in CI/non-TTY, only those packages are upgraded. A requested package that is not in `dependencies` or `devDependencies` is a hard error. A requested npm package with no recorded public npm or LPM.dev Registry-proxy source is also a hard error instead of a silent skip.

For npm alias declarations such as `"strip-ansi-cjs": "npm:strip-ansi@^6"`, target the local manifest key:

```bash
lpm upgrade strip-ansi-cjs
```

LPM CLI looks up metadata and lockfile source attribution through the canonical target (`strip-ansi`) while preserving the local key and `npm:strip-ansi@...` shape when it rewrites `package.json`.

In a TTY, `lpm upgrade` shows an interactive multiselect so you can pick which packages to bump. In CI or a non-TTY, it runs non-interactively. Override with `-i` (force interactive) or `-y` (force non-interactive).

The interactive multiselect annotates each candidate with the signals you'd want before saying yes: whether the upgrade target ships install scripts, whether any peer-dependency declaration shifts under your current lockfile, and whether an existing `lpm patch` for this package won't cleanly apply to the new version.

`lpm upgrade` honors the same [minimum release age](/docs/packages/install#recently-published-packages) policy for the direct dependencies it proposes. If the registry's latest version is still inside the cooldown window, upgrade selects the newest mature candidate at or below the current `dist-tags.latest` target instead of rewriting `package.json` to a version the install step would reject. This preserves a maintainer rollback even when an older release has a greater SemVer major.

## Examples [#examples]

```bash
lpm upgrade                # interactive at TTY, all-at-once in CI
lpm upgrade zod            # upgrade only zod
lpm upgrade zod react      # upgrade only these direct dependencies
lpm upgrade --dry-run      # show what would change
lpm upgrade --major        # also offer breaking upgrades
lpm upgrade -y --dry-run   # CI-friendly JSON/text preview of upgrade candidates
lpm upgrade -y             # non-interactive (skip prompts)
lpm upgrade -i             # interactive (even in non-TTY)
```

## Major upgrades [#major-upgrades]

```bash
lpm upgrade --major
```

In **non-interactive** mode, `--major` actually performs the major bump on every dep that has one. In **interactive** mode, major upgrades appear as separate rows in the multiselect — you toggle the ones you want.

After a `--major` run, review the changelog of every bumped package before shipping. LPM CLI never reads release notes for you.

## What changes [#what-changes]

* `package.json` — declared ranges are rewritten to match the new resolved versions, respecting your [save policy](/docs/packages/save-policy).
* `lpm.lock` — fully refreshed, with `lpm.lockb` refreshed when the graph fits the binary format.
* `node_modules/` — re-linked with the new versions.

If your `package.json` says `"react": "^18.0.0"` and the lockfile records `react` as coming from public npm or the configured LPM.dev Registry proxy, `lpm upgrade` will land `^18.3.1` when 18.3.1 is the newest mature matching 18.x release. With `--major` and a mature react 19 release available, it would also offer `^19.0.0`.

## Arguments [#arguments]

| Argument       | Effect                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| `<package...>` | Optional direct dependency names to upgrade. Names must already exist in `dependencies` or `devDependencies`. |

## Flags [#flags]

| Flag                  | Effect                                                                                                                                                  |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--major`             | Allow upgrading to a higher major version. Mutually exclusive with interactive mode — in interactive mode, major-bumps appear as togglable rows instead |
| `--dry-run`           | Show what would be upgraded without making changes                                                                                                      |
| `-i`, `--interactive` | Force interactive mode even outside a TTY. Mutually exclusive with `-y` and `--json`                                                                    |
| `-y`, `--yes`         | Force non-interactive mode (useful at a TTY). Mutually exclusive with `-i`                                                                              |

Plus the [global flags](/docs/commands#global-flags).

## See also [#see-also]

* [`lpm outdated`](/docs/packages/outdated) — see which deps have updates available
* [`lpm install`](/docs/packages/install) — reinstall after a manual `package.json` edit
* [Save policy](/docs/packages/save-policy) — how new ranges get saved
