vx lock runs every config once and saves the result. Every run reads it, and vx lock --check catches drift a file hash can't see.
config
config
vx lock runs every config once and saves the result. Every run reads
that file, so CI runs the config your reviewer saw. A TypeScript config
can depend on where it runs:
flowchart LR
C["vx.config.ts files"] -->|vx lock| L[.vx/projects.lock.json]
L --> R[vx run]
L --> W[vx watch]
L --> A[--affected]
C -->|vx lock --check| K{same result?}
K -->|no| X[exit 1]
vx lock is the only command that runs a config. It also checks the
graph rules. With no lock, a run stops:
Terminal window
$vxrunbuild--all
✗vxrunnolock:run`vx lock`
A project with no vx.config.*, whose tasks come from a plugin like
turbo(), is locked too: vx lock records what the plugin maps, and a
run reads that and maps nothing.
vx lock --check --format json gives the same exit code:
{"upToDate":false,"audited":4,"notAudited":0,"problems":["packages/d/vx.config.ts evaluates differently from the lock here — its config, a file it imports, or the environment it reads changed; run 'vx lock'\n tasks.build.exec.command: \"bun build src/index.ts --outdir dist --minify=false\" → \"bun build src/index.ts --outdir dist --minify=true\""]}
vx DTE puts each task on a machine type that can run it, books it by its measured memory peak and CPU, stops a server once nothing needs it, and prints how busy every worker was.
vx's CI is one run spread over its own Linux and Mac runners. On Nx Cloud's Team plan with Nx's agents, the same CI would cost about $12,192 a year. On vx it costs $0.
Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.