Dependency Management
Corral inspects your project’s dependencies and shows which ones are outdated, what safe updates are available, and lets you update them directly from the app.
How It Works
When you open the Dependencies tab for a project, Corral:
- Reads
package.jsonto find declared dependencies and their semver ranges - Parses the lock file (npm, yarn, pnpm, or bun) to determine installed versions
- Queries the npm registry to fetch all published versions for each package
- Computes two key versions per dependency:
- Wanted — the highest published version that satisfies the declared semver range (e.g., if your range is
^5.9.0, wanted might be5.9.5) - Latest — the highest published version overall (e.g.,
6.0.2)
- Wanted — the highest published version that satisfies the declared semver range (e.g., if your range is
- Classifies the update type as patch, minor, or major based on the version difference
Pre-release versions are excluded from both wanted and latest computations.
Version Caching
Version lists are cached per package (not per project) with a 1-hour TTL. If two projects both depend on typescript, the registry is queried once and both benefit from the cache. Refreshing the dependency list re-reads the lock file from disk but reuses cached registry data.
Updating Dependencies
Update N safe
The header button applies every safe row at once, by name, running your project’s own within-range update command. Nothing leaves the range you declared, so nothing breaks.
Whether it also touches package.json depends on the manager: npm and Yarn
Classic move only the lock file, while pnpm and bun rewrite the declared range
to the version they landed on. The section says which of those applies to your
project before you press it — see the per-manager
table.
Update to Wanted
Updates specific packages within their declared semver ranges. Available via the right-click context menu on selected rows. This is always a safe operation — it won’t introduce breaking changes.
Update to Latest
Updates specific packages to the absolute latest version, regardless of the declared range. This modifies package.json. A confirmation dialog warns about potential breaking changes.
Which package manager Corral uses
One answer, shared by everything: the Dependencies tab, the dev server Corral
starts for a project, corral pm, and the cpm shim. Corral resolves it in
this order and stops at the first match:
| Priority | Source | Set it with |
|---|---|---|
| 1 | Per-project override | The Package manager picker in a project’s Settings tab, or corral project set <project> package-manager pnpm |
| 2 | package.json packageManager | "packageManager": "pnpm@9.4.0" — the field corepack reads. devEngines.packageManager counts too, when the first is absent |
| 3 | .yarnrc.yml yarnPath | The line yarn set version writes. It is the declaration that decides — a project whose committed release is missing is still a Yarn project, and Corral says the release is missing rather than quietly running something else |
| 4 | A lockfile in the project directory | Whatever your last install wrote |
| 5 | App-wide default | Settings → Default package manager, or corral settings set default-package-manager pnpm |
| 6 | npm | Corral’s own default |
A declaration outranks a lockfile. A repository carrying pnpm-lock.yaml
and "packageManager": "yarn@4.9.1" runs yarn: the field is what somebody
wrote on purpose, and the lockfile is a record of what happened to run last.
It is also what corepack and every CI provider already honour, so Corral
agreeing with them is one less thing that behaves differently on your machine.
Corral looks for both files in the project directory and then upward, stopping at the repository root — a workspace declares for the packages under it. It never looks above your home directory.
corral pm --about prints every input it read, and the Dependencies tab header
shows which one applied next to the package count — so a project that resolves
to something other than its lockfile says so rather than looking wrong.
When the package manager a project needs is missing
If a project declares pnpm@9.4.0 and this machine has no pnpm at all, Corral
installs it and starts the project. That happens on every tier: without it the
project simply would not run. It happens in the background when you add the
project, and again — with a progress line — at the start that needs it.
On Pro, a declared version also wins over a different one you already have:
a project asking for pnpm@9.4.0 on a machine with pnpm 10 gets 9.4.0, the way
corepack would. On the free tier it runs your pnpm 10 and says so.
If the project declares no version at all, Corral offers rather than decides — the Dependencies tab shows an Install button, and so does the failure if the project was starting. Picking a major version for you is not something Corral should do quietly: running pnpm 12 against a lockfile written by pnpm 8 rewrites the lockfile.
Which version you get
The newest one that answers what the project asked for and runs on the
project’s Node. packageManager names one exact version, but
devEngines.packageManager may name a range — "^11" — and Corral honours it
as a range rather than looking for a package published under that literal name.
Package managers have Node requirements of their own: pnpm 11 needs Node 22.13 or newer, pnpm 9 needs 18.12. Where the project left room, Corral uses it and picks a version that runs. Where it named one exact version that cannot run, Corral says so instead of installing it anyway — *“pnpm 11.9.0 needs Node
=22.13, and this project runs Node v18.20.4”* — because npm would install it regardless and you would meet the same fact later, as a crash.
For yarn, which version you get also decides which yarn: Classic stopped at
1.22 and everything from 2.0 lives under a different package name. Corral reads
the dialect from your yarn.lock (or a .yarnrc.yml), so a Berry repository
is never handed Classic — which would rewrite the lockfile on the first
install. With no lockfile to read, you get what yarn@latest gives everyone
else: Classic.
When Corral cannot honour what you asked for
Some things an install cannot fix, and Corral says so rather than leaving you
to find out: a manager it does not run, a packageManager pointing at a URL,
and a yarnPath naming a release that is not in the repository. The
Dependencies tab shows a line under the header, and the daemon log records one
at every start.
bun is the deliberate exception. It is a runtime rather than a package manager
— bun run dev executes your script with bun instead of node — so choosing a
version of it is a real decision rather than a detail, and Corral leaves it to
you.
What Corral installs, and what it will not run
Corral never runs a package’s install scripts. That is not caution for its own
sake: pnpm 12 replaced its npm package with a small shim whose install script
downloads the real binary from somewhere else, with no rename and no warning,
and installing it the obvious way would have run a downloader Corral does not
control. So Corral reads what the package actually contains and installs the
platform build directly where there is one, and refuses to record an install
until something in it answers --version.
Supported managers
| Manager | Lockfile | Notes |
|---|---|---|
| npm | package-lock.json | |
| yarn (v1 & Berry) | yarn.lock | v1 vs Berry decided by asking the yarn that will run; the lockfile’s __metadata: key is the fallback |
| pnpm | pnpm-lock.yaml | |
| bun | bun.lock (legacy: bun.lockb) |
Setting an override is worth doing when nothing further down the table says what
you actually run — a package-lock.json left behind by one npm install in a
pnpm project that declares nothing, say. Priority 4 takes that stale file at its
word, because a lockfile is all it has; an override, or a packageManager
field, is somebody saying otherwise on purpose.
Semver Range Support
Corral uses npm-compatible semver range matching (via the node-semver library), supporting:
- Caret ranges:
^1.2.3 - Tilde ranges:
~1.2.3 - Exact versions:
1.2.3 - Comparators:
>=1.0.0 <2.0.0 - OR ranges:
^1.0.0 || ^2.0.0 - Hyphen ranges:
1.0.0 - 2.0.0 - X-ranges:
1.x,1.2.*
Non-standard specifiers like workspace:*, file:../, or git URLs will show ”—” for the wanted version.