Each case is a small workspace and the outcome a user would see. All six
tools run the same 984 cases, each in a sandbox.

diagram

vx 747b26f · Turborepo 2.11.10 · Nx 24.0.2 · Vite Task 1.4.0 · moon 2.6.5 · Nix 2.34.6 · 2026-11-07 · every case

The cases come from every tool's own tests

The cases are compiled from the test suites of Nx, Turborepo, Vite
Task, moon, Nix and vx. A case names no tool's config. It says which
projects exist, what each task runs, and what must hold afterwards.

diagram

A thin adapter turns the case into each tool's own config. The harness
marks each command as it starts and ends, so "ran" means it ran.

Where the scores split

Group Cases vx Nx Turborepo moon Vite Task Nix
graph 149 149 113 91 84 86 57
inputs 302 302 186 187 192 177 175
outputs 223 223 156 160 122 139 158
affected 97 97 57 68 69 0 0
watch 31 31 27 28 0 0 0
sandbox 18 18 0 1 0 1 15

A case a tool cannot express counts as not passed. Its users cannot get
that behaviour either.

Each case says why it matters

Args forwarded to a server reach it as typed, never expanded by a shell vx pass moon pass Nx fail seen.txt is "<0><0>…", expected "<$(id -u)><`id -u`>…" 

Every case carries three or four sentences on what goes wrong without
it. Here a second shell ran $(id -u), a command nobody typed.

vx misses 2 cases. Both need programs a dependency puts on PATH, which
vx left to the tools you already have.

All cases, filters and each tool's detail: Conformance.
More at vznjs.github.io/vx.

Originally published on the vx blog. vx is open-source (MIT) task orchestration with a build cache: vznjs.github.io/vx · GitHub.

Written with AI assistance.