vlt v1.4.0: faster macOS installs and --save-types
vlt v1.4.0 brings the global store to macOS for up to 3x faster installs on Node 26, plus a new --save-types flag.

vlt v1.4.0 is out, and this one is all about macOS. The global store that has been speeding up installs on Linux since v1.2.0 is now on by default on macOS too. Hardlinking file by file is the slowest way to place files on APFS, so until now macOS kept unpacking every tarball. Instead, vlt now clones each package directory out of the store with a single copy-on-write clonefile call, using the node:ffi module that ships with Node 26.1 and later. Clones share storage with the store until they are written to, so editing files in node_modules stays safe, and older Node versions (or a project on a volume that can't clone) fall back to unpacking as before. On a Mac running Node 26, reinstalling a project with a warm cache and lockfile is now up to 3x faster, most of it coming from far fewer filesystem syscalls:
| Time (mean ± σ) | User | System | |
|---|---|---|---|
| vlt v1.3.8 | 9.606 s ± 0.617 s | 4.619 s | 6.437 s |
| vlt v1.4.0 | 3.076 s ± 0.042 s | 0.775 s | 1.455 s |
Measured with hyperfine: vlt cache cleared once per version, 2 warmup runs, then 6 timed runs of vlt i, removing node_modules before each one. v1.4.0 ran 3.12 ± 0.21 times faster.
The other highlight is the new --save-types flag. Adding a package that ships no TypeScript types used to mean a second install for its @types/* package. Now vlt install express --save-types adds express to dependencies and the matching @types/express to devDependencies in one go, while a package that brings its own types, like zod, is added alone. It picks the newest non-deprecated @types/* version for the package's major, and you can turn it on for every install with "config": { "save-types": true } in your vlt.json. Thanks to @karlhorky for the request!
Other changes
- pnpm workspaces just work. In a monorepo that only declares its workspaces in pnpm-workspace.yaml, vlt now reads its packages list (after vlt.json and the package.json workspaces field), so vlt install links them and vlt ls lists them without needing a vlt.json. vlt init -w seeds vlt.json from those globs too. pnpm catalogs still need to move to vlt.json, see the pnpm migration guide.
- --scope runs in dependency order. vlt run, exec, version, pack, publish and pkg now sort the workspaces matched by a --scope query topologically, the same order -w and -r already use. With the default --bail, a failing dependency now stops its dependents from running.
- "-" graph modifiers remove dependencies. Setting a graph modifier to "-" used to crash installs with Dependency node could not be found and broke --frozen-lockfile and vlt ci. It now removes the dependency end to end, and vlt uninstall respects your modifiers too.
- Cleaner failures. When a command fails, vlt now aborts its pending registry requests and running scripts instead of forcing the process to exit. A failing workspace in vlt run -r or vlt exec -r stops the others, a 404 mid-install no longer dumps a raw stack trace, and background cache work and keychain saves still finish on the way out.
- Colliding aliases are a config error. Reusing a name across registries, jsr-registries and git-hosts (built-ins included) made spec parsing silently pick one, so --registries github=… would break github:user/repo specs. That is now an ECONFIG error when the config loads. Heads-up: if you have a registries.github (e.g. GitHub Packages) or registries.jsr entry, rename it, for example to gh.
- :outdated handles packages Socket hasn't scanned. vlt query ':outdated' no longer crashes with Cannot read properties of undefined (reading 'license') when a package version has no security scan yet.
- Smaller wins. The published vlt package now declares "type": "module" instead of relying on Node's module syntax detection, and semver range and lockfile parsing got a slightly faster string-splitting fast path.
Try it
You can find every patch note in the GitHub releases. To install or update vlt, run:
bash
curl -fsSL https://install.vlt.sh | bashOn macOS, run it on Node 26.1 or later to get the cloned installs.