CLI tool
vltpkg/vltpkg avatar
vltpkg/vltpkg

vltpkg: the monorepo behind the vlt JavaScript package manager

the vlt package manager monorepo

563 stars35 forksTypeScriptNOASSERTION

At a glance

What is it?
vltpkg is the source monorepo for the vlt package manager, published as vlt on npm, with the reusable client internals split into around thirty separately licensed packages such as @vltpkg/cache, @vltpkg/graph and @vltpkg/query. It is a TypeScript workspace built around a released CLI that bootstraps itself.
Who is it for?
vltpkg suits a JavaScript team that wants to reuse the pieces of a package manager client rather than only run it, since the cache, graph, query, config and registry client packages are individually published and individually licensed, and since the whole CLI can be run from source with a single script.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A monorepo whose packages are the point

The README opens with a three-word summary that tells you the project's ambition: Develop. Run. Distribute. This is the source monorepo for the vlt package manager, which is published to npm as vlt, and the homepage is vlt.sh with documentation at docs.vlt.sh.

What makes this repository interesting is that it is not only the CLI. The README documents a complete table of each workspace available in the repository and its corresponding licence, and the reusable client internals under src/ are broken into around thirty separately published packages. The listing includes @vltpkg/cache, @vltpkg/cache-unzip, @vltpkg/cli-sdk, @vltpkg/cmd-shim, @vltpkg/config, @vltpkg/dep-id, @vltpkg/dot-prop, @vltpkg/dss-breadcrumb, @vltpkg/dss-parser, @vltpkg/error-cause, @vltpkg/fast-split, @vltpkg/git, @vltpkg/git-scp-url, @vltpkg/graph, @vltpkg/graph-run, @vltpkg/init, @vltpkg/keychain, @vltpkg/output, @vltpkg/package-info, @vltpkg/package-json, @vltpkg/pick-manifest, @vltpkg/promise-spawn, @vltpkg/query and @vltpkg/registry-client, with more after the truncation point of the README.

The names describe a package manager's internals with unusual honesty. There is a dependency graph package, a query package, a manifest parser, a keychain wrapper, a Git client, a command shim generator, a cache and a cache unzip. Those are the pieces you would otherwise have to write to build a registry client, and publishing them separately is the decision that turns this from a private implementation into a set of reusable dependencies.

Licensing is per workspace, not per repository

The licence situation needs reading carefully, and the README makes the point that a single repository can hold a mixture. The root is classified as a custom licence GitHub cannot classify, with the LICENSE file as the authoritative text, and the package.json for the monorepo itself declares BSD-2-Clause-Patent.

Inside the table, most of the reusable internals carry BSD-2-Clause-Patent, including cache, cache-unzip, cli-sdk, cmd-shim, config, dep-id, dss-breadcrumb, dss-parser, error-cause, fast-split, git-scp-url, graph, graph-run, init, keychain, output, package-info, package-json, pick-manifest, query and registry-client. Two are MIT, @vltpkg/dot-prop, and two are ISC, @vltpkg/git and @vltpkg/promise-spawn.

The pattern is understandable rather than arbitrary. BSD-2-Clause-Patent is the permissive-with-patent-grant licence that companies tend to reach for when the code may later be patented, MIT is used for small utility packages where simplicity matters, and ISC covers the two packages that are thin wrappers over Git and process spawning. For a consumer this means the licence obligations differ per package depending on which one you import, so the practical instruction is to read the licence row for the specific package rather than assuming the repository's root licence covers everything.

Bootstrapping the monorepo from source

The contributing section gives a complete setup sequence, and it has an unusual feature that says a lot about how the project is organised. Development requires Git, Node.js 22.22.x and the latest released vlt CLI, with the repository's .nvmrc selecting the supported Node.js major when using nvm.

bash
# Clone the repository
git clone https://github.com/vltpkg/vltpkg.git
cd vltpkg

# Install and select the Node.js version from .nvmrc
nvm install
nvm use

# Install the released CLI used to bootstrap the repository
curl -fsSL https://install.vlt.sh | bash

# Install dependencies and prepare generated workspace files
vlt install
vlr --recursive prepare

# Run the CLI directly from source
./scripts/bins/vlt --version

The structure of that sequence is the interesting part. The repository is bootstrapped using the released CLI rather than the source it contains, which avoids the circular dependency of a package manager that has to install itself. Then vlt install resolves dependencies and vlr --recursive prepare generates workspace files. Finally ./scripts/bins/vlt --version runs the CLI straight from the checkout, which tells you the source layout has a bins directory with executable entry points.

There is a second command, vlr, which the README does not explain directly but which the package.json reveals as the workspace script runner, with scripts/bins/vlr and scripts/bins/vlrx as its entry points. The recursive prepare step is what makes vlr necessary, since a monorepo of this size needs a tool that can run a command across every workspace.

Why vlt setup is skipped here

One line in the README is a good illustration of how the tool separates concerns. vlt setup is not required for this repository. That command connects the CLI to a vlt.io account, and this repository's checked-in vlt.json already configures the registry used to bootstrap its dependencies.

So the CLI has an account-linking step, and the monorepo opts out of it because it does not need an account to resolve its own dependencies. The registry configuration lives in a checked-in file, which means a contributor's first install pulls from the same registry configuration as everyone else's rather than depending on personal login state. For a user of the published CLI, the distinction is what you want to know: there is a setup step that binds the tool to a hosted account, and it is not needed for local use against a registry your own configuration names.

What the monorepo scripts say about the toolchain

The package.json is named @vltpkg/vltpkg, is marked private, and sits at version 1.5.0, matching the newest release tag. It carries a vlt-lock.json alongside the vlt.json configuration, so the lock file format is the project's own rather than a converted npm lockfile.

The devDependencies list is instructive because of how it uses the catalog protocol. Entries such as @eslint/js, @types/node, @types/semver, @types/ssri, eslint, prettier, typescript and typescript-eslint are declared as catalog:, meaning the version is defined once centrally rather than repeated per workspace. The workspace packages are declared as workspace:*, including @vltpkg/benchmark, @vltpkg/cli-sdk, @vltpkg/graph, @vltpkg/infra-build, @vltpkg/query, @vltpkg/semver and @vltpkg/types, which is how internal packages are linked without publishing them first.

The scripts show the shape of the internal tooling. There is a build:bundle script calling vlt-build, a deps:check script pointing at a script in the scripts directory, fix and fix:pkg scripts that run a consistency script for package.json files across the tree, format and format:check using prettier with a cache and a .prettierignore, knip for unused dependency detection, lint and lint:check using eslint, and vlr and vlrx wrappers for the workspace script runner. The repo also carries eslint.config.mjs, knip.ts, tsconfig.json, tap-config.yaml, an AGENTS.md, a CODE_OF_CONDUCT.md, a SECURITY.md and a coverage-map.js, so the project has the full set of governance and quality files you would expect from a commercially maintained tool.

How this differs from using npm, pnpm or yarn

The comparison worth making is not vlt against other tools on speed, since the README does not make speed claims and the README gives no benchmark numbers. The comparison is about what a package manager is made of and what it publishes.

npm, pnpm and yarn all ship primarily as a single binary. Their internals are not generally available as separately licensed npm packages that you can consume in your own tooling, so if you want to reuse a resolver, a lockfile parser or a registry client, you either use their CLIs or you write your own. vlt's monorepo publishes the internals, with @vltpkg/graph and @vltpkg/query carrying the dependency graph and query logic, @vltpkg/registry-client the registry protocol, @vltpkg/package-json and @vltpkg/pick-manifest the manifest handling, and @vltpkg/dss-parser and @vltpkg/dss-breadcrumb the lockfile format handling that the vlt-lock.json file implies.

That difference has a real consequence. A tool that wants to analyse a dependency graph, or read a lockfile produced by vlt, or embed a registry client, can depend on the same code the CLI uses rather than reimplementing it. The cost is that you are taking on a dependency set with mixed licences and a fairly young versioning history, and the benefit is that the behaviour matches what the CLI actually does rather than what a reimplementation guesses.

Where vltpkg is the wrong place to look

Three limits are clear. The first is that this repository is not what you install. If you want vlt as your package manager, the deliverable is the vlt package on npm and the install script at install.vlt.sh; the monorepo is for contributors and for consumers of the internals. A reader expecting an install guide for a package manager will find that the interesting content is a development setup sequence for the maintainers, not a getting-started for users.

The second is the bootstrap dependency. Development requires the latest released vlt CLI, so you cannot work on the CLI without first installing the previous version of it. That is a deliberate design to avoid a circular bootstrap, but it does mean the repository is not self-hosting, and a contributor without network access to the install script cannot get started.

The third is the licensing mixture, revisited from the consumer side. A large organisation with a policy that a dependency must be under one approved licence has to check each of the around thirty packages separately, because the table shows three different terms in use. Nothing here is restrictive, since all three are permissive, but uniform is not what the repository offers.

On maintenance, the release history is fast. The tags are v1.5.0 from 2026-10-20, v1.4.0 from 2026-10-14 and v1.3.8 from 2026-10-09, and the last push to the repository was on 2026-10-20, so the tree and the tags are moving together. The repository is not archived and carries a SECURITY.md and a CODE_OF_CONDUCT.md.

Editorial conclusion

vltpkg suits a JavaScript team that wants to reuse the pieces of a package manager client rather than only run it, since the cache, graph, query, config and registry client packages are individually published and individually licensed, and since the whole CLI can be run from source with a single script. It is the wrong tool if you want to install packages, because the deliverable for that is the vlt binary on npm, not this repository, and it is the wrong tool for a project that cannot accept a mix of BSD-2-Clause-Patent, MIT and ISC terms across the packages it consumes. Verify first which of the @vltpkg packages you intend to depend on and read the licence table row for it, and note that the newest release is v1.5.0 from 2026-10-20 with the last push on the same day.

Frequently asked questions

What is vltpkg and how is it different from the vlt package manager?

vltpkg is the source monorepo for the vlt package manager, which is published to npm as vlt. The monorepo additionally publishes the reusable client internals under src/ as separate @vltpkg packages, each with its own licence.

How do I set up the vltpkg repository for development?

Clone the repository, run nvm install and nvm use to select the Node.js version from .nvmrc, install the released CLI with curl -fsSL https://install.vlt.sh | bash, then run vlt install and vlr --recursive prepare. The CLI can then be run from source with ./scripts/bins/vlt --version.

Which licences apply to the vlt packages?

The table in the README lists them per workspace. Most reusable internals under src/ are BSD-2-Clause-Patent, @vltpkg/dot-prop is MIT, and @vltpkg/git and @vltpkg/promise-spawn are ISC. The root LICENSE file is the authoritative text for the repository itself.

Why is vlt setup not needed when working in the vltpkg repository?

The README says vlt setup is not required for this repository because that command connects the CLI to a vlt.io account, and the checked-in vlt.json already configures the registry used to bootstrap the dependencies.

What are vlt and vlr in the vltpkg scripts?

vlt is the package manager CLI and vlr is the workspace script runner, with the package.json wiring them to ./scripts/bins/vlt, ./scripts/bins/vlr and ./scripts/bins/vlrx so commands can be run from source. The fix script chains them, running vlr fix:pkg and then vlr lint and vlr format.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. vltpkg/vltpkg on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vltpkg-vltpkg.svg)](https://hysenlabs.com/projects/vltpkg-vltpkg)

Was this useful?