Seven open-source monorepos that already run on Turborepo or Nx, timed under their own runner and under vx: cold, cache restore, one-file edit and a clean clone. Raw seconds, min of three, slower rows included.
benchmarks
benchmarks
The synthetic benchmark runs one generated
graph. This post times repos someone else wrote: open-source monorepos
that already use Turborepo or Nx, each moved to native vx config, then
run under both tools on the same machine.
Both tools build the same outputs; that is the assumption behind every
row.
One cloud container: 4 vCPU (Intel Xeon @ 2.10GHz), 15 GB RAM, Linux,
nothing else running. Bun 1.4.2, Node 22.22.0.
vx built from main with bun build --compile: 522c23b for
create-t3-turbo, react-email, trpc and typescript-eslint; 731cf92 for
vercel/ai, medusa and TanStack query; 1ee058c for the react-email clone
row.
Configs written by bunx @vzn/vx-migrate --native --no-install, then
vx lock.
Concurrency 10 for every tool: Turborepo --concurrency=10, Nx
--parallel=10, vx --concurrency 10.
Local cache only: no remote cache, no daemon, no telemetry.
Four arms, each tool wiping only its own cache:
cold: cache and every build output wiped.
restore: outputs wiped, cache kept.
edit: one source file gets a new line (new content each rep),
outputs kept.
clone: a fresh git clone at another path, node_modules
copied, sharing the first checkout’s cache, with no outputs.
Three reps, the order alternating between tools. Each cell is the
minimum of the three, in seconds. Every run exited 0.
Both edit rows are a rerun on vx 5b2b0a1 (same machine shape, min of
3). The second sets cache.outputs.clean: false on the three tsc build
tasks: by default vx deletes a task’s declared outputs before it runs on
a miss, tsc’s .cache/tsbuildinfo.json included, so tsc rebuilds api
from scratch.
We traced one workspace through vx, Turborepo 2.11.8 and Nx 23.3.0, step by step, cold and warm. Most of a run is the tasks themselves. The rest is a list of choices, and some of vx's extra work is there on purpose.
A task reads src/a.ts, and while it runs, something writes src/a.ts. Which cache entry gets saved? We read the source of vx, Turborepo, Nx and Vite Task to find out. Each made a different trade.
Turborepo is fast and stops at the edge of a laptop. Nx scales and is a product with a runner attached. Between a tool that will not grow and a platform that will not get out of the way, the thing a large JavaScript monorepo actually needs did not exist. That is why vx does.
Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.