Turn the cache off, refresh it, or read one layer and write another. Every clone and worktree of a repo shares one store. And a pull request never writes what main reads.
Caching
Caching
A cache is only useful when you can tell it what to do. vx gives you three
switches for a run, one store for every checkout, and a scope that keeps
untrusted runs from writing what everyone else reads.
--force runs everything again and refreshes the cache with the result.
--no-cache neither reads nor writes. For finer control, --cache takes
a read/write spec per layer:
Terminal window
$vxrunbuild--all--cache=local:rw,remote:r# read the remote, never upload
$vxrunbuild--all--cache=local:r# read local, write nothing local
$vxrunbuild--all--cache=local:,remote:rw# skip local, still upload
An empty spec is refused, never read as “everything on”:
Terminal window
$vxrunbuild--all--cache=
vxrun:--cacheneedsaspeclikelocal:r,local:rw,remote:,orlocal:,remote:rw—pass--no-cachetodisableeveryaxis (see `vx run --help`)
Artifacts live in ~/.vx/<id>/cache, where the id comes from the repo’s
remote. Each checkout keeps only its own small index. So a second clone
or a fresh git worktree hits what the first one built:
The new worktree had no dist. All four builds came back from the shared
store in 22ms. To put the cache somewhere else, use --cache-dir,
VX_CACHE_DIR or cacheDir in vx.workspace.ts.
A remote cache is shared, so a write is a promise to everyone who reads
it. cacheScope decides where a run’s writes land:
flowchart LR
M[main CI · trusted] -->|reads + writes| T[(trusted keys)]
P[PR CI · pr-123] -->|reads| T
P -->|writes| S[(pr-123 keys)]
L[laptop · read-only] -->|reads| T
style T stroke:#c6f84e,stroke-width:2px
trusted reads and writes the task keys. This is the default on CI.
read-only reads the task keys and writes nothing. This is the default on a laptop.
Any other name, like pr-123, reads its own keys first, then the
trusted ones, and writes only its own. A pull request never writes what
main reads.
VX_CACHE_SCOPE beats the config. On GitHub Actions, the
@vzn/vx-ci plugin
sets the scope for you: pr-<n> on a pull request, trusted on the
default branch. The scope is a client-side rule, so a cache server that
checks tokens is still the real boundary.
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 run picks the project you stand in. Off a terminal it never waits on a picker. On GitHub Actions every task folds into its own log group. Plus colors that respect FORCE_COLOR=0, and a build edge for packages that ship as source.
Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.