upm 1.4 adds overrides, link: dependencies and git dependencies from GitHub, GitLab and Bitbucket. It also makes installs much harder to tamper with: a changed lockfile, store or tarball can no longer give you another package's code without upm noticing. On a normal install these checks cost almost nothing.
Important
Some installs that used to pass with a warning now fail. Read Upgrading at the end of these notes before you update CI.
✨ Highlights
Overrides and resolutions (#22)
upm now reads npm overrides, yarn resolutions, pnpm.overrides and the overrides in pnpm-workspace.yaml. The rules apply to the whole tree, including workspaces and peer ranges, and are saved in upm.lock.
{
"overrides": { "minimatch": "^9.0.5", "eslint": { "ajv": "6.12.6" } },
"pnpm": { "overrides": { "glob@<9": "9.3.5", "request>form-data": "-" } }
}Rules nested more than one parent deep (a>b>c) and values upm can't install (patch:, portal:, workspace:) are skipped with a warning.
link: dependencies (#25)
upm add lib@link:../lib # saves "lib": "link:../lib"This works as it does in pnpm and yarn. upm symlinks the folder into node_modules and links its bins, but does not install the folder's own dependencies. The path is relative to the package.json that declares it and may point outside the project.
Git dependencies on GitHub, GitLab and Bitbucket (#26)
upm add github:unjs/ufo#v1.5.4 # or unjs/ufo#v1.5.4upm does not run git. It downloads the host's archive for the ref and installs it like any tarball, so upm.lock pins the exact bytes. You can use github:, gitlab:, bitbucket:, user/repo, and git+https://, git+ssh:// or git@host: URLs.
Limits:
- Build scripts (
prepare) are not run. - Private repositories are not supported.
- Pin a tag or commit: a branch moves, and the locked bytes then stop matching.
🚀 Enhancements
install --verifynow hashes stored and installed files, and repairs any that differ (4976b3f)- Warn when a package's
engines.nodedoes not include the Node you are running (665c0c9) - Warn about overrides, resolutions and patches that upm can't apply (b0896b0)
- Warn about locked versions published after the release age cutoff, with no extra requests (1385dfd)
- Warn once when a registry gives no publish dates, so release age can't be checked (bae22f4)
- Warn when a locked tarball URL is not on any configured registry (d61d823)
🔒 Security
Each fix below stops an edited lockfile, store or tarball from installing the wrong code.
- Every tarball and store entry is checked against the package that was asked for: name, version and integrity (b27ccc0)
- A registry package locked to a URL outside its registry is refused unless the registry publishes the same integrity. Scoped packages are checked against their own registry, which closes a dependency-confusion gap (fb40df5, 8da7bb4)
- Lockfile entries must match
package.jsonfor every dependency, alias and workspace (f1a69b3, 1834623) - Imported
package-lock.json,pnpm-lock.yamlandbun.lockfiles are checked againstpackage.jsontoo (5bbe0db) - A peer dependency can resolve to an alias or tarball only if the dependent package declares that peer (c08870b)
- Cached tarballs are reused only for the URL and integrity they were checked against (b568a66, 7c007bf)
🩹 Fixes
Running installs at the same time
- Only one install at a time relinks a
node_modulesfolder (5a747d2) - The lock is released when you stop an install with Ctrl+C (03f0d13)
- A lock left by a crashed install is taken over at once on Linux, macOS and Windows. A crashed
upm addno longer causes a 10-second wait (ac8abba, f2dbcd9, f72339b) - Running
addandinstallat the same time no longer mixes up their files (bc78eba)
Lockfile
- A locked version outside its
package.jsonrange now counts as stale (4ad66a5) - A failed install no longer writes the lockfile (4ad66a5)
Store and cache
- Damaged cached metadata is fetched again, and project files are written atomically (9bab3c6)
- Damaged store entries are refilled (4d29805)
- A tarball whose bytes don't match its integrity is downloaded once more before failing (42b8aa2)
- A skipped optional dependency is fetched on the next install (0a54e92)
- Direct links are checked before a tree counts as up to date (b3b707f)
Platforms
- Bins published with Windows line endings (
#!/usr/bin/env node\r\n) now run on Linux and macOS (#24) - On case-insensitive disks, packages with two file names that differ only in case link correctly, and
--verifyno longer repairs them on every run (6f27459, 72d663b) - A dependency named
constructor,toStringor another built-in property name now installs (6b9b7a3) - Safari support in the browser build (4ef0593, 96cd547, 4e4a148)
🔥 Performance
- Fewer registry requests for platform-specific optional dependencies such as
@next/swc-*,@esbuild/*and@rolldown/binding-*(a2e7514, aaa30c3) - Fewer duplicate requests for scoped packages on a slow registry (b0dc1ba)
- A store filled by an older upm is updated once, and later relinks are faster (024235b)
⚠️ Upgrading
Installs that may now fail
- Lockfile URLs outside a package's registry fail with
ELOCKunless the registry publishes the same integrity for that version. They used to only warn. Mirrors that serve the registry's exact bytes still work, at one extra metadata request per entry if the mirror isn't configured. Offline with no cached metadata, they fail withEOFFLINE. - JSR packages need
@jsr:registryin.npmrc. Without it, a lockfile with JSR entries fails withELOCK. - Imported lockfiles must match
package.json. Apackage-lock.json,pnpm-lock.yamlorbun.lockthat doesn't fails withELOCK. An importedpackage-lock.jsonwith anhttps://tarball dependency is refused. - Peers on aliases or tarballs must be declared. A hand-edited lockfile that resolves a peer to an alias or tarball the dependent doesn't declare as a peer fails with
EMISMATCH. - Optional dependencies whose lockfile entry fails a check now fail the install instead of being skipped.
One-time effects
- Projects with overrides in
package.jsonre-resolve on the first install.--frozen-lockfilefails untilupm.lockis rewritten. - Offline installs of URL tarball dependencies from an older store fail with
EOFFLINEuntil one online install records where each tarball came from. - Local
file:tarballs are hashed once more, and older store indexes are rewritten once. Downgrading still works.
Known caveat
- The release cutoff warning reads the date from the tarball's
last-modifiedheader. The registry sometimes re-uploads old tarballs, so an old version can be flagged by mistake. This is rare with the default 1-day cutoff.