Bun-native No daemon MIT licensed

The monorepo orchestrator
you were waiting for

A build tool shouldn't make you choose between fast and flexible, or between powerful and free. vx is fast and simple from the first task, fully extensible in real TypeScript as you scale, and yours to keep — no daemon, no proprietary cloud, nothing to lock you in.

Get started
2× Faster cold builds vs Turbo & Nx
0.55s Full cache replay 3,270 tasks
50× Less CPU burned vs Turbo & Nx
zsh — vx
vx run build --affected
241ms success miss @vzn/vx#build.bun.darwin-x64
243ms success miss @vzn/vx#build.bun.linux-arm64
242ms success miss @vzn/vx#build.bun.darwin-arm64
245ms success miss @vzn/vx#build.bun.linux-x64
vx 0.0.0────────────────────────────────────────────────────────────────────────────────
projects ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱
1 affected · 2 total
tasks ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰
4 success · 4 total
cache ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰
4 miss
info10 workers · local cache
time 252ms · max 245ms · avg 243ms · min 241ms

// only in vx

What sets vx apart.

The cache understands your config

vx.config.ts is evaluated before hashing, so imports, shared presets and computed values all participate in the cache key. Change a preset and exactly the right tasks re-run. Turbo and Nx hash static JSON — they can’t see this.

Outputs are owned

Declared outputs are wiped before every run and every restore, so your tree ends bit-identical to the cache — stale files cannot survive. Turbo and Nx are additive: leftovers linger.

No daemon to babysit

One binary, no Node, nothing long-lived. On a clean tree, every cache key comes from the git index with zero file reads — 3.2× faster warm at 15k files. Nx needs a daemon for this; vx doesn’t.

Per-task kernel sandbox

Run any task under an OS-level file + network allow-list with sandbox: {}. An undeclared read or a phone-home fails the build instead of hiding it. No other runner has it.

A cache that can’t be poisoned

Trust-scoped remote cache: a fork PR reads main’s cache to stay fast but can only write its own quarantined scope — a poisoned artifact never reaches a trusted build. Artifacts are immutable, and HMAC signing verifies bytes on top. The GitHub-Actions model, server-enforced.

Reproducible when you want

vx lock freezes the fully-resolved task graph into vx-lock.json; --frozen runs skip evaluation entirely and run exactly that graph. No other runner has an equivalent.

// beyond a task runner

The open platform layer.

One binary. Eight surfaces. Every contract is documented; every wire is JSON-RPC 2.0. Subscribe, query, drive, extend — your stack, your tools, your data.

// 3,270 tasks

Lower is better. We checked.

vx turborepo nx

Cold build · from scratch

vx 3m 48s
turbo 8m 18s
nx 8m 27s

Fully cached · nothing to rebuild

vx 0.55s
turbo 1.60s
nx 9.86s

Restoring outputs · cache → disk

vx 0.89s
turbo 2.00s
nx 10.44s

CPU burned · cold build, user time

vx 22.7s
turbo 1,250s
nx 2,038s

vx builds the whole graph in under 4 minutes where Turborepo and Nx take over 8 — burning ~50× less CPU doing it. Once cached, every repeat run replays in under a second, and Nx never catches up.

// configuration

Config is just
TypeScript.

Not JSON, not YAML. vx.config.ts is evaluated before hashing, so imports, shared presets and computed values all participate in the cache key. Tasks are shell commands; declare inputs and outputs with full type-safety.

Read the config reference
vx.config.ts
// vx.config.ts — next to any package.json
import { defineProject } from '@vzn/vx'
export default defineProject({
tasks: {
build: {
exec: { command: 'tsc -b' },
dependsOn: ['^build'],
cache: {
inputs: { files: ['src/**'] },
outputs: { files: ['dist/**'] },
},
},
test: {
exec: { command: 'bun test' },
dependsOn: ['build'],
cache: { inputs: { files: ['src/**'] }, outputs: { files: [] } },
},
},
})

// migrate

Switch in an afternoon.

vx migrate converts your turbo.json or Nx project graph into a real vx.config.ts. The mapping is mechanical — keep your task graph and your speed, drop the daemon and the plugins.