One command scaffolds a working plugin and its test. Bring your own remote cache through one small interface, hook setup and teardown around the run, or drive vx from your own scripts with run() and planRun().
Plugins
Plugins
vx is a pipeline with seams. This post is the
practical side: how to write a plugin today, and how to call vx from
code.
flowchart LR
I[vx init --plugin cache] --> P[plugins/cache.ts]
I --> T[plugins/cache.test.ts]
P --> W[vx.workspace.ts]
T --> B[bun test]
style P stroke:#c6f84e,stroke-width:2px
Drop --dry and the files are written. Every seam has a template:
executor, cache, telemetry, schedule, admit, commands,
project, graph and key. Each one runs, and its test drives it
through a real run(). The templates are the same files vx’s own gate
runs, so they cannot rot.
Swap the directory for S3, R2 or your own HTTP server. LayeredCache
does the rest: the local cache stays in front, a remote error turns into
a miss and a warning, uploads run in the background, and every artifact
gets the same integrity check as a local one. vx bounds no call, so a
network store gives each request its own deadline. A plugin’s name is its
package name, taken from import.meta.
setup(ctx) runs before the first task, and teardown runs after the
last. Use them to start a service, take a lock, or flush a report. A
setup that throws stops the run with a clean error naming the plugin.
A teardown cannot hold the exit hostage: it gets 3 seconds, which
VX_TEARDOWN_TIMEOUT_MS changes.
vx prune --production leaves out the workspace packages only dev dependencies pull in, and strikes them from the copied manifests and lockfile, so the image that runs your app installs frozen without them.
vx docs <query> searches the CLI, config and cache reference that ships inside vx. No network, no site: the sections that match print whole, with their URL.
Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.