Getting Started With vlt, an npm Alternative
Assess vlt as an npm alternative: set up registries, migrate an existing project, manage lockfiles and build scripts, and query dependencies before switching.
vlt is a free, open-source JavaScript package manager made by people who created and maintained npm.
vlt became a serious option once 1.0 shipped. It installs from package.json, splits installs into a download step and a script step, and ships a query language for your dependency graph. The friction comes from the details: lockfiles, .npmrc auth, postinstall scripts and, most of all, which registry your packages come from. This guide goes through all of those on an existing project and ends with a clear verdict.
Key Takeaways
- vlt has no default registry in its current client docs. Before installing, you either point the
npmalias at a registry withvlt config set registries=npm=…or runvlt setupto use your vlt.io account’s registries. vlt installruns no dependency scripts.vlt buildthen runs lifecycle scripts for every package that has them, skipping packages with known malware alerts unless you narrow the target with a selector.- vlt ignores
package-lock.jsonand resolves the tree again intovlt-lock.json, so transitive versions can change when you switch. vlt queryuses CSS-style selectors such as:scripts,:malwareand:prodto pick packages out of your resolved dependency graph.
What Is the vlt Package Manager and Who Built It?
vlt is a package manager client plus a hosted registry service, and it comes from people who built npm. The November 2024 launch post, signed by Darcy Clarke, Ruy Adorno and Luke Karrys, introduced it as free and open source. vlt 1.0 shipped on August 4, 2026, and 1.x releases have followed since.
The vlt CLI will look familiar to npm users. The architecture is different. If you are weighing it against the other main npm alternative, see how pnpm approaches the same problems.
Install vlt and Run It on an Existing Project
You can install vlt with the official script or through npm. After that, vlt install fetches your dependencies and vlt build runs their scripts.
# official installer, then configure a registry and account
curl -fsSL https://install.vlt.sh | bash
vlt setup
# or install through npm
npm install -g vlt
cd your-project
vlt install # resolve, download, extract; no dependency scripts run
vlt build # run lifecycle scripts for eligible packages
The npm route is listed in the npm migration guide. A registry has to be configured before vlt install will run. The configuration docs say vlt ships with no default, and any command that has to reach a registry stops with a config error until you set one.
You will work with two files in the project root:
vlt.json: project configuration, taking over from.npmrc.vlt-lock.json: vlt’s lockfile.
According to the npm migration guide, vlt does not read package-lock.json. It resolves everything from scratch. You can delete the old lockfile, or keep it while both tools run side by side. This is less gentle than pnpm’s lockfile import, covered in switching from npm to pnpm. Diff the resolved versions before you merge anything.
| npm | vlt |
|---|---|
npm install | vlt install |
npm ci | vlt ci (shorthand for vlt install --expect-lockfile) |
npm rebuild (runs scripts) | vlt build |
npm config set registry=… | vlt config set registries=npm=… |
npm ls | vlt list |
npm explain <pkg> | vlt query '#<pkg>' |
Is vlt a Drop-In Replacement?
Treat “drop-in” as something you test, not something you assume. The 2024 launch post said vlt could replace your existing package manager “in most cases”. The 1.0 post goes further and calls the client a drop-in replacement for npm. Both statements come from the vendor. Check these five areas on your own project:
.npmrcsettings. The docs don’t say vlt reads.npmrc. Registry and scope settings belong invlt.jsonunderscoped-registries. Auth tokens go in vlt’s keychain file or inVLT_TOKENenvironment variables, as described in the npm migration guide. Private scopes are where a migration usually breaks first.- Install-script packages. Native addons and packages that download a binary won’t work until
vlt buildhas run (see below). - Peer dependencies. The install docs say vlt aims for one copy of each peer dependency. If two parts of the tree need peer versions that can’t live together, vlt gives each part its own peer context. Trees that fail with npm’s ERESOLVE error may resolve under vlt, possibly with more than one copy of the peer.
- Workspaces. Monorepos have a separate page in the vlt docs. Check your layout against it.
- CI. Use
vlt cifollowed byvlt build.
A regression caused by switching package managers can pass CI and first show up in production. A different transitive version, or a skipped postinstall that should have generated a file, can surface as a browser runtime error. Session replay with console and network capture connects that error to the deploy that changed the lockfile.
The Registry: Where Your Packages Come From
The vlt client has no default registry. You choose one. The registries docs say install commands (vlt install, vlt ci, vlx and others) need the npm registry alias to be set. A plain registry value from vlt.json, a flag or VLT_REGISTRY is not enough for them. The other route is vlt setup, which configures your vlt.io account’s registries.
Running vlt setup changes your source of packages. It points the npm alias at your account’s mirror on vlt’s registry. The vlt homepage says every request for a public package goes through a security check on that mirror, which blocks known malware. Your trust root moves from npm to vlt.
To use the public npm registry directly, run:
vlt config set registries=npm=https://registry.npmjs.org/
Run inside the project, this writes the alias to the project’s vlt.json. Commit that file so the whole team and CI use the same source.
One caveat: an issue filed in April 2026 reports that vlt install keeps using the registry URLs recorded in an existing vlt-lock.json. If you switch registries, regenerate the lockfile.
Registry blocking only stops malware that has already been identified. A newly published malicious version can still get through until someone flags it. Teams that need private hosting can also self-host vsr, vlt’s npm-compatible, Fair Source registry, which the launch post offers for local, self-hosted or managed use.
Security Defaults: Phased Installs and vlt build
vlt install runs no dependency scripts. vlt build then runs lifecycle scripts for every package that has them, except packages with known malware alerts, unless you narrow the target with a selector. The build docs give the default target as:
:scripts:not(:built):not(:malware)
There is no approval prompt. You approve scripts by writing a narrower Dependency Selector Syntax query. Pass it as the build target, or use --allow-scripts on install, and save it to vlt.json so the whole team uses the same one. The vlt build announcement walks through the model.
In practice, phased installs mean that a package that needs a postinstall script to fetch a prebuilt binary or compile a native addon is not built after vlt install. Anything that depends on its binary or generated files can fail until vlt build runs. Put vlt build in every setup script and CI job.
The idea matches disabling npm install scripts by default. Consumer-side controls only protect installs, though. On the publishing side, check package contents with npm pack --dry-run so you don’t ship files you didn’t mean to.
Dependency Graph Queries With vlt query
vlt query picks packages out of your resolved dependency graph with CSS-style selectors, much as querySelectorAll picks elements out of a page. The 1.0 post counts more than 60 graph pseudo-selectors, about 30 of them security-focused. vlt’s insights selectors post says the security selectors use Socket metadata.
vlt query ':scripts' # packages with install scripts
vlt query ':malware' # packages with known malware alerts
vlt query ':prod' # production dependencies only
vlt query ':scripts' --view=mermaid # render matches as a Mermaid diagram
The query docs list the output modes: human, json, mermaid, svg, png and count. Start with :scripts, because that list is what vlt build chooses from by default (it then skips packages already built and packages with malware alerts). According to vlt’s host-context post, :host(local) runs a query across the projects configured in vlt’s dashboard.
The same selectors work in CI:
- run: npm install -g vlt
- run: vlt ci # vlt install --expect-lockfile
- run: vlt build
- name: Report dependencies with malware alerts
run: vlt query ':malware' --view=count
To make that last step fail the job, add --expect-results=0, which the query docs describe. The query stays the same everywhere: it is your policy, stored as a single selector string.
Verdict: Worth a Side Project, Not Yet the Default
vlt is worth trying on a side project now. A production team should keep its current package manager until its own CI, private registry auth and install-script packages all run cleanly under vlt. Phased installs and vlt query are useful. The fresh lockfile resolution and the choice of registry need a deliberate decision. If install speed is what you care about most, compare against pnpm 12’s Rust rewrite on your own repository.
Start on a branch. Set the npm registry alias explicitly, run vlt install, vlt build and vlt query ':scripts', and diff the resolved versions in vlt-lock.json against your old lockfile before anything reaches main.
FAQs
What Node.js version does vlt require, and does it still create a node_modules folder?
The vlt package requires Node.js 22.22 or later. vlt still writes a node_modules directory, but it uses its own internal layout under node_modules/.vlt/. That is different from npm's flat tree. By default, vlt hard-links files from a global store on Linux and unpacks each package on macOS and Windows; the store-linker setting changes this. Packages still resolve normally at runtime, so your application code should not need to change.
What replaces npx and npm run when using vlt?
vlt exec replaces npx. You can also call it as vlt x or with the vlx shortcut. It runs a package binary and downloads the package if it is not in node_modules, asking first before it fetches anything new. vlxl only runs binaries that are already installed. vlt run, shortened to vlr, runs package.json scripts with their pre and post hooks. Both accept a --scope selector to target workspaces.
How do I migrate npm overrides to vlt?
vlt's equivalent of npm's overrides field is Graph Modifiers. You define them in vlt.json and write them as Dependency Selector Syntax queries. This lets you target a dependency by path, workspace or semver range, not just by package name. When more than one modifier matches the same dependency, vlt uses CSS-like specificity rules to decide which one wins.
How do I configure workspaces in a vlt monorepo?
vlt reads the workspaces field of your root package.json as it is, so an existing npm or yarn monorepo works without changes. Use the workspaces field of the root vlt.json when you want named groups or are moving off pnpm-workspace.yaml. If vlt.json has a workspaces field, vlt uses only that and ignores the package.json field; the two are not merged. In vlt.json the value can be a glob string, an array of globs such as packages/*, or an object of named groups that each map to paths or globs. A plain array goes into the default group, called packages.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k