- Published on
Scoped Releases: New version, pack, and publish commands
- Authors
- Name
- Luke Karrys
- Bluesky@lukekarrys.com
--scope
: version
, pack
, publish
Manage releases across workspaces with Releasing changes in a growing project or monorepo shouldn't require bespoke scripts. vlt
now supports graph-aware release operations with version
, vlt pack
, and vlt publish
. Each command supports the full Dependency Selector Syntax via --scope
. You can bump versions, create tarballs, and publish only the workspaces you intend. We also added --publish-directory
to both pack
and publish
so you can bundle into a directory (e.g. dist/
) before packaging or publishing.
tl;dr
vlt version <inc>
with--scope="<selector>"
bumps the version in matched packages.vlt pack --scope="<selector>"
creates tarballs in each matched package.vlt publish --scope="<selector>"
publishes matched workspaces.vlt pack
andvlt publish
use--publish-directory=<path>
to publish from a different output directory.--scope
accepts the full selector syntax and works great with workspaces.
Why this is useful
- Target only what matters: release a subset of workspaces (e.g., apps, services) without touching the rest.
- Bundle first, then ship: build to a different directory during
prepack
, then pack/publish only the artifacts using--publish-directory
. - Safer, repeatable flows: version, then pack to verify artifacts, then publish. All of this is driven by selectors.
How it works
vlt
evaluates the selector passed with --scope
against your project's dependency graph. For version
, pack
, and publish
, matched items are typically your configured workspaces. version
applies the increment to each matched workspace. pack
produces npm-compatible tarballs, and publish
sends packages to your registry. Both pack
and publish
respect --publish-directory
to run from a different working directory.
For the complete selector reference, see the docs: Dependency Selector Syntax.
Examples
Version a package by name and all its workspace dependencies
$ vlt version patch --scope="#package-a, #package-a :workspace"
package-a: v1.4.1
package-b: v1.2.1 # dependent on package-a
package-c: v3.2.1 # dependent on package-b
app-
Version a subset of workspaces that start with $ vlt version patch --scope=":workspace[name^=app-]"
app-web: v1.2.4
app-admin: v0.9.1
./apps
Version prereleases for apps found in $ vlt version prerelease --scope=':path("apps/*")'
apps/web: v1.4.1-pre.0
apps/api: v2.8.4-pre.0
apps/admin: v0.9.1-pre.0
Version and pack workspaces by name
Use this flow to validate artifacts before publishing.
$ vlt version minor --scope=':workspace:is(#web, #api)'
web: v1.4.0
api: v2.9.0
$ vlt pack --scope=':workspace:is(#web, #api)'
๐ฆ Package: [email protected]
๐ File: web-1.4.0.tgz
๐ 52 Files
... (truncated)
๐ Package Size: 1.2 MB
๐ Unpacked Size: 1.1 MB
๐ Shasum: ...
๐ Integrity: ...
๐ฆ Package: [email protected]
๐ File: api-2.9.0.tgz
๐ 108 Files
... (truncated)
๐ Package Size: 2.9 MB
๐ Unpacked Size: 2.8 MB
๐ Shasum: ...
๐ Integrity: ...
Version and publish all public workspaces
$ vlt version patch ":workspace:not(:private)"
app-web: v1.4.1
app-server: v2.9.1
$ vlt publish ":workspace:not(:private)" --tag=latest
๐ฆ Package: [email protected]
๐ท๏ธ Tag: latest
๐ก Registry: https://registry.npmjs.org/
๐ 52 Files
... (truncated)
๐ Package Size: 1.2 MB
๐ Unpacked Size: 1.1 MB
๐ Shasum: ...
๐ Integrity: ...
๐ฆ Package: [email protected]
๐ File: app-server-2.9.1.tgz
๐ 108 Files
... (truncated)
๐ Package Size: 2.9 MB
๐ Unpacked Size: 2.8 MB
๐ Shasum: ...
๐ Integrity: ...
--publish-directory
during prepack
and then pack and publish
Build to Bundle to dist/
during prepack
, then package/publish from that directory. This allows you to publish a set of files that is completely different than what is in the source directory. This is helpful when bundling or compiling your project before publishing.
package.json
:
{
"name": "app-web",
"version": "1.4.1",
"private": false,
"scripts": {
"prepack": "vite build && cp package.json dist/ && cp README.md dist/"
}
}
Pack from dist/
:
$ vlt pack --scope="#app-web" --publish-directory=dist
Publish from dist/
:
$ vlt publish --scope="#app-web" --publish-directory=dist --tag=latest
prepack
script
Publish all packages that have a You can combine this with selectors to publish many packages that follow the same build layout.
$ vlt publish --scope=':workspace:path("packages/*"):attr(scripts, [prepack])' --publish-directory=dist --tag=latest
๐ฆ Package: @org/[email protected]
๐ File: @org/foo-0.7.0.tgz
๐ 52 Files
... (truncated)
๐ Package Size: 1.2 MB
๐ Unpacked Size: 1.1 MB
๐ Shasum: ...
๐ Integrity: ...
๐ฆ Package: @org/[email protected]
๐ File: @org/bar-3.2.1.tgz
๐ 108 Files
... (truncated)
๐ Package Size: 2.9 MB
๐ Unpacked Size: 2.8 MB
๐ Shasum: ...
๐ Integrity: ...
Learn more
Have questions or feedback about --scope
, --publish-directory
, or releasing with vlt
? Join us on Discord or open an issue on GitHub.