Skip to content
vznjsPublic

Repository files navigation

vx logo

vx

Task orchestration you own.
Correct, sandboxed, extensible. No cloud, no account, no paywall.
vznjs.github.io/vx

npm CI MIT license Documentation

What vx is

Task orchestration with a cache you can trust, on a core you can extend. Each task is one shell command with declared inputs and outputs; vx runs them in dependency order and replays results from a content-addressed cache.

Quick start

In a git repo:

bunx @vzn/vx init   # installs vx, writes an empty root vx.config.ts and the lockfile plugin

A prebuilt binary for Linux (glibc, not Alpine's musl) and macOS, x64 and arm64. Windows: run vx inside WSL2.

A task runs its tool directly, never through a package script. Cache one by saying what it reads and writes:

// packages/app/vx.config.ts
import { defineProject } from '@vzn/vx/config'

export default defineProject({
  tasks: {
    build: {
      exec: { command: 'tsc -b' },
      dependsOn: ['^build'], // dependencies build first
      inputs: { files: ['src/**', 'tsconfig.json'] },
      cache: {
        outputs: { files: ['dist/**'] },
      },
    },
  },
})
vx run build --all    # builds, in dependency order; stores the results
vx run build --all    # nothing changed: up-to-date, in milliseconds
rm -rf packages/*/dist
vx run build --all    # restored from the cache, not rebuilt

vx run ci --all on examples/basic: cold, three tasks run; again, three up-to-date.

When to run vx lock

init also writes .vx/projects.lock.json, every project's config as it evaluated. Commit it. Every run reads its configs from the lock, so run vx lock and commit the lock again after you:

  • edit any vx.config.ts or .vx/workspace.ts,
  • update dependencies or plugins,
  • change a file a config imports.

Otherwise runs keep the old configs. On CI, vx lock --check fails a stale lock before any task runs.

Starters: examples/basic, and examples/ci with a GitHub Actions workflow; CI runs both on every commit. The CI guide explains the workflow. More: Quickstart · Configure · CLI · every config field.

A foundation you own

  • A cache you can trust: TypeScript configs are evaluated before hashing, so imports and computed values are in the key. Outputs are wiped before every run and restore: no stale file survives.
  • Sandboxed tasks: opt in per task; a workspace file the task did not declare is out of its reach, so it cannot poison the cache.
  • Clean exits: Ctrl-C reaps each task's process group.
  • Plugins at every stage (15 hooks, commands included): remote cache, remote execution, telemetry, CLI verbs. Core ships none and needs none.
  • Free: MIT. No paywall, no cloud, no account.

Plugins

What vx can do, not what it is limited to. Declared in .vx/workspace.ts; without any, vx runs and caches locally.

Package What it adds
@vzn/vx-migrate Migrate from Turbo or Nx: write native configs, keep its remote cache
@vzn/vx-reapi Remote cache and remote execution over Bazel's REAPI (NativeLink, BuildBuddy)
@vzn/vx-lockfile Key each project on its own lockfile slice: pnpm, bun, npm, yarn
@vzn/vx-otel OpenTelemetry traces, metrics and logs, no SDK
@vzn/vx-ci GitHub Actions job summary and Checks API
@vzn/vx-history Schedule by the critical path learned from past runs
@vzn/vx-cache Remote cache for CI jobs, on a vx cache server
@vzn/vx-cache-server The cache server you host: Bun or Docker with S3, or Workers with R2
@vzn/vx-history-server The task timings server vxHistory() reads: Bun, Docker or Workers
@vzn/vx-devtools Code the servers and plugins share: the CI OIDC token check
@vzn/vx-dte Spread one run over workers your own CI starts (not on npm yet)
@vzn/vx-dte-server The relay dte() meets its workers at: Workers, Bun or Docker (not on npm yet)

Hosting the three servers: servers docs.

Write your own: plugin guide · architecture.

Coming from Turbo or Nx

Beside turbo.json or nx.json, bunx @vzn/vx init runs @vzn/vx-migrate: it writes a vx.config.ts per package from turbo.json or the Nx graph, and you keep those and delete the old config. vx init --keep writes only a .vx/workspace.ts that maps the old config instead, and its lock: a temporary start, not a way to run the repo. The benchmark below uses native vx config. Migration guide.

How it compares

vx Turborepo Nx
Config TypeScript, evaluated into the cache key JSON (static) JSON (static)
Output ownership Strict: wiped before exec and restore Additive (stale files survive) Additive
Clean-tree hashing No source reads (git index OIDs) git OIDs re-hash / daemon
Daemon None None for turbo run On by default
Per-task sandbox Yes: kernel-level, opt-in, local No On Nx Cloud only
Plugin API Yes: every pipeline stage No Yes (TS-tied)
Install Single binary; no Bun, Node optional npm + Node npm + Node

Every gap, and when another tool is the better pick: comparison · vx, Turborepo, Nx, Bazel.

Fast, without trading correctness

  • Nothing boots per task: no daemon, no Node process; vx spawns your command.
  • No source-file reads to hash: on a clean tree, keys come from git's index; each project's package.json and the lockfile are still read.
  • One pass: one git walk per run; each stat and lookup happens once.
Time added over the ideal run, 1,601 projects, 9,603 tasks vx Turborepo Nx Vite Task
Nothing changed 799 ms 927 ms 24.15 s 12.07 s
Nothing changed, outputs restored 1.28 s 2.01 s 24.45 s 11.86 s
Cold build 7.57 s 9.63 s 3 min 6 s 9.01 s
Cold build: CPU the runner burns 36.64 s 1 min 12 s 5 min 34 s 25.32 s

Time each tool adds over the ideal run; lower is better.

Benchmark workload: a synthetic monorepo of 1,601 projects and 9,603 tasks in 30 dependency levels, five core libraries a quarter of the projects use; build 300 ms, test and typecheck 150 ms, lint 75 ms, publish 30 ms; real repos with uneven task times will differ. Run 2026-10-25 on linux x64, 4 cores: vx at commit 9abdfb52c, Turborepo 2.11.10, Nx 24.0.1, Vite Task (vite-plus) 1.4.0.

Same graph, commands and concurrency: how it is measured.

Status

Pre-alpha, dogfooded: this repo lints, tests and builds itself with vx. The schema may still change; 1.0's promise: versioning-1.0.md.

Issues

vx is maintained by VZN and takes issues, not pull requests: report a bug or ask for a feature in issues.

License

vx is MIT licensed. The prebuilt binaries embed Bun and a few npm packages under permissive licenses; their notices ship as THIRD_PARTY_NOTICES.txt in each platform package and GitHub release.

Releases

Packages

Used by

Contributors

Languages