# vx > vx is a Bun-native task runner and content-addressed cache for JavaScript monorepos. Tasks live in TypeScript configs (`vx.config.ts`), a run is `vx run `, and plugins decide where tasks run and where the cache lives. Every page below is plain markdown. Every Docs and Reference page in one file: https://vznjs.github.io/vx/llms-full.txt. An agent in a vx workspace can also ask the workspace itself: `vx mcp`, and `--format json` on `vx show`, `vx info`, `vx why` and `vx last` (https://vznjs.github.io/vx/guides/agents.md). ## Docs - [AI agents](https://vznjs.github.io/vx/guides/agents.md): Let a coding agent run vx, read its answers as JSON, and ask the workspace about its cache and history. - [CI and remote](https://vznjs.github.io/vx/guides/ci.md): Choose what a run covers, run only what a change affects in CI, share the cache between machines, and send tasks to a worker pool. - [Configure](https://vznjs.github.io/vx/guides/configure.md): Tasks and dependencies, caching, environment variables, dev servers, the workspace file and lockfiles, one section each. - [Migrate](https://vznjs.github.io/vx/guides/migrate.md): Move a Turborepo, Nx or Vite Task repo to native vx config. `vx init` writes the vx.config.ts files that are the goal; `vx init --keep` gives a temporary start. - [Plugins](https://vznjs.github.io/vx/guides/plugins.md): Write a plugin that fills one or more stages of every run, export runs to OpenTelemetry, and let an AI agent read your workspace with vx mcp. - [Sandboxing tasks](https://vznjs.github.io/vx/guides/sandboxing.md): Run a task where only the workspace files you declared exist, so an undeclared input cannot hide in the cache. - [Troubleshooting](https://vznjs.github.io/vx/guides/troubleshooting.md): What vx printed, what it means, and the fix. - [Upgrading to 1.0](https://vznjs.github.io/vx/guides/upgrading.md): Every breaking change before 1.0, newest first, and what to do about it. - [Try it](https://vznjs.github.io/vx/playground.md): vx's own planner in your browser, on four small packages. Edit a file, the environment or a config, run, and read which tasks would run and why. - [Quickstart](https://vznjs.github.io/vx/quickstart.md): Install vx, describe one task, and run it from the cache the second time, in a new repo or one you already have. ## Reference - [Every feature](https://vznjs.github.io/vx/all-features.md): Every user-facing feature of vx, one line each, grouped by what it is - [API reference](https://vznjs.github.io/vx/api.md): Every export of @vzn/vx, generated from src/index.ts by - [Benchmarks](https://vznjs.github.io/vx/benchmarks.md): Empirical overhead numbers vs. Turborepo and Nx on synthetic workspaces. - [Caching](https://vznjs.github.io/vx/caching.md): cascade through the dependency graph the same way Turborepo's does. - [CLI reference](https://vznjs.github.io/vx/cli.md): The vx binary is the user-facing entry point. The implementation is - [vx, Turborepo, Nx, Bazel](https://vznjs.github.io/vx/compare.md): The design choices behind each tool, what each buys and what it costs, and when another tool is the better pick. - [vx vs Nx](https://vznjs.github.io/vx/compare/nx.md): The same 1,090-package graph run by both, what each one asks of you, what Nx keeps for Nx Cloud, and when Nx is the better pick. - [vx on real repos](https://vznjs.github.io/vx/compare/real-repos.md): Public monorepos moved to vx and timed against the tool they ship with, with the commit, versions and machine for every number. - [Config support for Turbo and Nx](https://vznjs.github.io/vx/compare/turbo-nx-support.md): Every key turbo.json, nx.json and project.json accept, read from the upstream schemas (@turbo/types 2.11.5, nx 23.2.1), and what @vzn/vx-migrate's turbo()… - [vx vs Turborepo](https://vznjs.github.io/vx/compare/turborepo.md): The same 1,090-package graph run by both, what each one asks of you, and when Turborepo is the better pick. - [Compared to Turborepo, Nx, vite-task](https://vznjs.github.io/vx/comparison.md): A side-by-side reference for what each of the four tools does, plus an - [Built for the agents that run your builds](https://vznjs.github.io/vx/concepts/ai-first.md): vx is AI-first. An agent asks what to run, runs it, and learns why it failed, all as typed JSON. People get the same answers as text. - [Why vx is fast](https://vznjs.github.io/vx/concepts/why-vx-is-fast.md): The engineering behind vx's speed and its correctness guarantees — git-OID hashing, bitset scheduling, strict output ownership, and a daemonless design — with measured numbers. - [Task execution lifecycle](https://vznjs.github.io/vx/execution.md): This document traces what happens between vx run build typed at the - [Glossary](https://vznjs.github.io/vx/glossary.md): One tool-neutral definition per term, with the name each tool uses for it. - [The diagram kit](https://vznjs.github.io/vx/internals/diagrams.md): The site's build-time SVG picture component and the data it draws from, each part rendered with the toy monorepo. - [@vzn/vx-ci](https://vznjs.github.io/vx/plugins/vx-ci.md): GitHub Actions integration for @vzn/vx — a - [@vzn/vx-lockfile](https://vznjs.github.io/vx/plugins/vx-lockfile.md): Lockfile plugins for @vzn/vx: pnpm(), bun(), npm() and yarn(). Each keys every task on its own project's resolved dependency closure from the package… - [@vzn/vx-mcp](https://vznjs.github.io/vx/plugins/vx-mcp.md): A Model Context Protocol server for - [@vzn/vx-migrate](https://vznjs.github.io/vx/plugins/vx-migrate.md): Everything for adopting @vzn/vx from Turborepo, Nx or Vite Task, in one package with zero dependencies: - [@vzn/vx-otel](https://vznjs.github.io/vx/plugins/vx-otel.md): The OpenTelemetry exporter plugin for @vzn/vx. - [@vzn/vx-reapi](https://vznjs.github.io/vx/plugins/vx-reapi.md): A vx remote cache backed by any server speaking Bazel's - [@vzn/vx-schedule-history](https://vznjs.github.io/vx/plugins/vx-schedule-history.md): History-based scheduling for @vzn/vx: a schedule plugin that orders ready tasks by their expected REMAINING critical-path duration — a task's own p50 plus… - [Config schema](https://vznjs.github.io/vx/schema.md): Complete reference for every field accepted by vx.config.{ts,mts,js,mjs,cts,cjs} - [Security model](https://vznjs.github.io/vx/security.md): What vx trusts, what it checks, what the sandbox stops and what it does ## Blog - [A run you can read](https://vznjs.github.io/vx/blog/a-run-you-can-read.md) - [A scheduler that learns from your runs](https://vznjs.github.io/vx/blog/a-scheduler-that-learns.md) - [Run only what a change reaches](https://vznjs.github.io/vx/blog/affected.md) - [Give your coding agent the build's memory](https://vznjs.github.io/vx/blog/agents-and-mcp.md) - [Bitsets, popcount, and a scheduler tick that re-scans nothing](https://vznjs.github.io/vx/blog/bitsets-and-the-scheduler.md) - [Built for the agent at the keyboard](https://vznjs.github.io/vx/blog/built-for-agents.md) - [Cascade through dependencies by folding input keys, never outputs](https://vznjs.github.io/vx/blog/cascade-through-inputs.md) - [Config in TypeScript, and why there are no named inputs](https://vznjs.github.io/vx/blog/config-in-typescript.md) - [How many tasks at once? Count the cores you are given](https://vznjs.github.io/vx/blog/cores-in-a-container.md) - [Ctrl-C leaves nothing running](https://vznjs.github.io/vx/blog/ctrl-c.md) - [Dev servers as graph nodes: readiness instead of sleep](https://vznjs.github.io/vx/blog/dev-servers-in-the-graph.md) - [See the plan before you run it](https://vznjs.github.io/vx/blog/dry-run.md) - [A task sees only the env it names](https://vznjs.github.io/vx/blog/env-isolation.md) - [A refusal an agent can read](https://vznjs.github.io/vx/blog/error-codes.md) - [Errors that say the fix](https://vznjs.github.io/vx/blog/errors-that-say-the-fix.md) - [Explicit over magical: why vx never guesses your inputs](https://vznjs.github.io/vx/blog/explicit-over-magical.md) - [Extend vx in an afternoon](https://vznjs.github.io/vx/blog/extend-vx.md) - [Flags you already know](https://vznjs.github.io/vx/blog/flags-you-already-know.md) - [Flaky is a claim only declared inputs can back](https://vznjs.github.io/vx/blog/flaky-tasks.md) - [Moving to vx from Nx: keep the graph, drop the platform](https://vznjs.github.io/vx/blog/from-nx.md) - [From npm scripts or Vite Task](https://vznjs.github.io/vx/blog/from-scripts-and-vite-task.md) - [Moving to vx from Turborepo: a temporary start, then native config](https://vznjs.github.io/vx/blog/from-turborepo.md) - [Guard rails that tell you the fix](https://vznjs.github.io/vx/blog/guard-rails.md) - [Hello, vx](https://vznjs.github.io/vx/blog/hello-vx.md) - [Benchmarks you can re-run](https://vznjs.github.io/vx/blog/honest-benchmarks.md) - [What goes into a key, and what comes back](https://vznjs.github.io/vx/blog/inside-a-cache-hit.md) - [A key with nothing to run](https://vznjs.github.io/vx/blog/keyed-groups.md) - [Your cache key is already in git's index](https://vznjs.github.io/vx/blog/keys-from-git.md) - [One command to know your workspace](https://vznjs.github.io/vx/blog/know-your-workspace.md) - [vx lock: freezing what the key sees](https://vznjs.github.io/vx/blog/lock-and-frozen.md) - [A lockfile bump should re-key two tasks, not sixty](https://vznjs.github.io/vx/blog/lockfile-aware-keys.md) - [There was no choice on the market](https://vznjs.github.io/vx/blog/no-choice-on-the-market.md) - [No daemon, on purpose](https://vznjs.github.io/vx/blog/no-daemon.md) - [One binary, nothing to install underneath](https://vznjs.github.io/vx/blog/one-binary.md) - [One command per task; the shell is the API](https://vznjs.github.io/vx/blog/one-command-per-task.md) - [Watch a CI run while it runs](https://vznjs.github.io/vx/blog/otel-live.md) - [Output that fits the run](https://vznjs.github.io/vx/blog/output-that-fits-the-run.md) - [Say exactly which tasks to run](https://vznjs.github.io/vx/blog/pick-your-tasks.md) - [A pipeline with seams](https://vznjs.github.io/vx/blog/pipeline-with-seams.md) - [A runtime image without the dev tools](https://vznjs.github.io/vx/blog/prune-production.md) - [A remote server you can trust in production](https://vznjs.github.io/vx/blog/reapi-in-production.md) - [Remote execution without moving the scheduler](https://vznjs.github.io/vx/blog/remote-execution.md) - [Configs are programs. Hash what they evaluate to.](https://vznjs.github.io/vx/blog/resolved-config-hashing.md) - [Your run, on the pull request](https://vznjs.github.io/vx/blog/results-on-github.md) - [Which task runs first?](https://vznjs.github.io/vx/blog/scheduling-strategies.md) - [See inside a run](https://vznjs.github.io/vx/blog/see-inside-a-run.md) - [The tree is exactly the snapshot](https://vznjs.github.io/vx/blog/strict-output-ownership.md) - [When a task misbehaves](https://vznjs.github.io/vx/blog/tasks-that-misbehave.md) - [Observability that cannot break a run](https://vznjs.github.io/vx/blog/telemetry-never-breaks-a-run.md) - [The basics, done carefully](https://vznjs.github.io/vx/blog/the-basics.md) - [The cache on your terms](https://vznjs.github.io/vx/blog/the-cache-on-your-terms.md) - [The local floor: running here is not a plugin](https://vznjs.github.io/vx/blog/the-local-floor.md) - [Try the planner in your browser](https://vznjs.github.io/vx/blog/the-playground.md) - [The sandbox: turning a declaration into a boundary](https://vznjs.github.io/vx/blog/the-sandbox.md) - [The small things](https://vznjs.github.io/vx/blog/the-small-things.md) - [An upgrade you can trust](https://vznjs.github.io/vx/blog/upgrade-you-can-trust.md) - [Performance, modularity, extensibility. In that order.](https://vznjs.github.io/vx/blog/values.md) - [The reference, offline](https://vznjs.github.io/vx/blog/vx-docs-offline.md) - [The last run, on request](https://vznjs.github.io/vx/blog/vx-last.md) - [Ship one app, not the whole monorepo](https://vznjs.github.io/vx/blog/vx-prune.md) - [See what a task really is](https://vznjs.github.io/vx/blog/vx-show.md) - [Watch: a content gate, not an event storm](https://vznjs.github.io/vx/blog/watch-mode.md) - [What vx is, and what it refuses to be](https://vznjs.github.io/vx/blog/what-vx-is.md) - [One failure, and exactly what it takes down](https://vznjs.github.io/vx/blog/when-a-build-fails.md) - [Why did this re-run?](https://vznjs.github.io/vx/blog/why-did-this-rerun.md) - [Why vx is fast: five decisions, not a trick](https://vznjs.github.io/vx/blog/why-vx-is-fast.md) ## Releases - [Start from Turbo or Nx in one line](https://vznjs.github.io/vx/releases/vx-0-0-199.md) - [The foundation](https://vznjs.github.io/vx/releases/vx-0-0-21.md) - [Starts 2× faster](https://vznjs.github.io/vx/releases/vx-0-0-242.md) - [Fewer surprises when you switch](https://vznjs.github.io/vx/releases/vx-0-0-325.md) - [The Turbo and Nx flags you already type](https://vznjs.github.io/vx/releases/vx-0-0-360.md) - [Ready for Docker and pull requests](https://vznjs.github.io/vx/releases/vx-0-0-495.md) - [One cache for every checkout](https://vznjs.github.io/vx/releases/vx-0-0-520.md) - [Every cache key known before a task runs](https://vznjs.github.io/vx/releases/vx-0-0-589.md) - [Runs that explain themselves](https://vznjs.github.io/vx/releases/vx-0-0-625.md) - [vx speaks to agents](https://vznjs.github.io/vx/releases/vx-0-0-632.md) - [Affected runs that include dependents](https://vznjs.github.io/vx/releases/vx-0-0-75.md) ## Internals (for contributors) - [Architecture](https://vznjs.github.io/vx/architecture.md): This is the design map of @vzn/vx. Read it after - [Design notes](https://vznjs.github.io/vx/design.md): Forward-looking proposals and historical design notes for vx — the record of what was explored and why. - [Adoption tooling leaves core (2026-09-10)](https://vznjs.github.io/vx/design/adoption-tooling-2026-09.md): Core reads no other runner's format. vx init (package.json scripts) - [--affected blind to config import closures — design](https://vznjs.github.io/vx/design/affected-config-imports-2026-08.md): A vx.config. may import any file it likes. The cache key sees the - [Architecture north star — the unified vision](https://vznjs.github.io/vx/design/architecture-north-star-2026-06.md): Status: VISION MOSTLY MATERIALIZED 2026-06-21. Originally a synthesis - [Architecture Overhaul — June 2026 Implementation Plan](https://vznjs.github.io/vx/design/architecture-overhaul-2026-06.md): fixed, every concern isolated behind a module interface, every flow - [Architecture review — sharpening the five proposals](https://vznjs.github.io/vx/design/architecture-review-2026-06.md): Status: MOSTLY APPLIED 2026-06-21. See "Applied" snapshot below. - [Architecture review — simplify, DX, develop further (2026-07)](https://vznjs.github.io/vx/design/architecture-review-2026-07.md): The core runner is in good shape (the consulting review's verdict holds: - [Cache save CPU — design](https://vznjs.github.io/vx/design/cache-save-cpu-2026-10.md): Cold run, 1,090 packages / 2,180 tasks, 1,090 saves of a tiny dist/: - [Validity-filtered caching (replaces output-fold early cutoff)](https://vznjs.github.io/vx/design/cache-validity-2026-06.md): Status: superseded (2026-06-13) by the pure-input transitive - [Capability audit: monorepo.tools, row by row (2026-09-24, roadmap track W)](https://vznjs.github.io/vx/design/capability-audit-2026-09.md): The site plan (design/site-teaches-2026-09.md) sets monorepo.tools as the - [Config lock — vx lock / vx-lock.json (2026-06)](https://vznjs.github.io/vx/design/config-lock-2026-06.md): vx configs are programs (vx.config.ts is evaluated, not parsed). - [Developer scenarios — one dev inside a huge monorepo (2026-07)](https://vznjs.github.io/vx/design/dev-scenarios-2026-07.md): Owner ask: "Create development scenarios. As a developer working locally in a - [Plugin-named projects: a discover stage (2026-09-28, stream D)](https://vznjs.github.io/vx/design/discover-seam-2026-09-28.md): (discoverProjects, orchestrator/projects.ts; namedProject, - [Download policy + deferred outputs (2026-08)](https://vznjs.github.io/vx/design/download-policy-cas-cache-2026-08.md): With remote execution (@vzn/vx-reapi phase 2, shipped), a task runs on - [Run event stream + devframe surfaces](https://vznjs.github.io/vx/design/event-stream-2026-06.md): Status: proposal (2026-06-17). Owner-driven: "drive our current terminal - [Integrity & robustness audit — May 2026](https://vznjs.github.io/vx/design/integrity-audit-2026-05.md): Recent PRs (#86–#95) tightened the cache-hit hot path significantly: - [The key fuzzer: a differential probe for stale hits (2026-10-02)](https://vznjs.github.io/vx/design/key-fuzzer-2026-10.md): task: a run is minutes of vx run spawns, and a seed that finds nothing - [Labs and checkpoints (2026-09-24, roadmap W10 and W11)](https://vznjs.github.io/vx/design/labs-checkpoints-2026-09.md): W9 shipped the playground: vx's real planner, bundled from core's source - [The landing page (2026-09-24, roadmap W8, item 709)](https://vznjs.github.io/vx/design/landing-2026-09.md): The site plan (design/site-teaches-2026-09.md) orders W8 last, - [A sandboxed task reads a linked sibling unseen (2026-09-24)](https://vznjs.github.io/vx/design/linked-sibling-reads-2026-09.md): and from the workspace root (linkedDeps). It reports denials only - [stable-key local cache short-circuit — design](https://vznjs.github.io/vx/design/local-cache-shortcircuit-2026-06.md): A cacheable task that is a confirmed local cache hit today waits for - [Local cache — v10 → v13](https://vznjs.github.io/vx/design/local-cache-v10.md): ├── cache.db SQLite metadata + run history - [Module isolation — design](https://vznjs.github.io/vx/design/module-isolation-2026-06.md): enforces them: 30+ cross-directory imports target internal files - [Monorepo structure — design](https://vznjs.github.io/vx/design/monorepo-structure.md): seven subdirectories that already behave like modules (cache/, - [The mutation sweep: method and rules (2026-09-18 → 09-21)](https://vznjs.github.io/vx/design/mutation-sweeps-2026-09.md): one source file or region at a time; item 572's verdict is that the - [An Nx repo under vx with nothing written (2026-09-22)](https://vznjs.github.io/vx/design/nx-unchanged-2026-09.md): (packages/vx-migrate/src/nx-exec.cjs), the nx() plugin - [Observability + integration architecture — design](https://vznjs.github.io/vx/design/observability-architecture-2026-06.md): The core/cloud split gave us a typed VxPlugin and an eventSink capability, - [Adversarial audit — vx terminal output layer](https://vznjs.github.io/vx/design/output-audit-2026-07.md): Scope: src/orchestrator/{logger,framed-output,status-line,summary,tally,colors,run-report,run-artifacts}.ts - [Two cached tasks, one output path (2026-09-20)](https://vznjs.github.io/vx/design/overlapping-outputs-2026-09.md): the survey met its own gate (three repositories with the addition - [Parity ledger audit (2026-09-23, item 659, roadmap 2.3)](https://vznjs.github.io/vx/design/parity-audit-2026-09.md): The two parity ledgers, turbo-nx-parity-2026-07.md and - [Persisted stable keys — design](https://vznjs.github.io/vx/design/persisted-stable-keys-2026-09.md): On a warm no-op run (476 packages, 952 tasks, all hits) deriveStableKeys - [The pipeline — plugin API v2 (2026-09)](https://vznjs.github.io/vx/design/pipeline-2026-09.md): followed. The verb move-out happened DIFFERENTLY from the plan below and - [The plan after the sweep week (2026-09-22)](https://vznjs.github.io/vx/design/plan-2026-09-22.md): they land, each with its number; a section here is struck through in - [The parallel plan (2026-09-27)](https://vznjs.github.io/vx/design/plan-2026-09-27.md): stream's merged items are recorded in docs/history/ws-id.md. - [The playground spike (2026-09-23, item 676, roadmap W9)](https://vznjs.github.io/vx/design/playground-spike-2026-09.md): W9 is the playground: vx's real planner running in the browser over a - [The playground page (2026-09-24, roadmap W9, item 700)](https://vznjs.github.io/vx/design/playground-ui-2026-09.md): W9's last step is the page the playground bundle exists for. The reader - [Per-task executor seam + @vzn/vx-reapi (2026-08)](https://vznjs.github.io/vx/design/plugin-executor-reapi-2026-08.md): Owner decision, 2026-08-22: vx-cloud is too complex to set up and work with. - [README and site: what drives adoption (2026-09-27)](https://vznjs.github.io/vx/design/readme-site-2026-09.md): Stream K's study of 15 dev-tool READMEs and four landing pages, and what - [Remote cache — protocol design](https://vznjs.github.io/vx/design/remote-cache.md): The local cache (docs/caching.md) makes one machine's repeat runs fast. - [Resource reservations learned from history (2026-09)](https://vznjs.github.io/vx/design/resource-estimates-2026-09.md): well. The number a task needs is a property of its inputs and the - [Resource-aware scheduling — design](https://vznjs.github.io/vx/design/resource-scheduling-2026-07.md): Today the scheduler admits a ready task on ONE constraint: the running - [Roadmap to 1.0 (2026-09-23)](https://vznjs.github.io/vx/design/roadmap-10.md): The question this answers: when is vx feature complete, and what is left - [Workspace-root tasks (2026-09-28, stream D)](https://vznjs.github.io/vx/design/root-project-2026-09-28.md): The two runners vx adopts both have tasks that live at the workspace - [Turbo vs Nx vs vx — operation-by-operation breakdown](https://vznjs.github.io/vx/design/runner-comparison-2026-05.md): The rest of this doc is per-phase deep-dives. Cells call out what - [Turbo vs Nx vs vx — full scenario matrix + test-coverage gaps](https://vznjs.github.io/vx/design/runner-scenarios-full-2026-05.md): Every scenario row has six cells: - [Runtime inputs — design (2026-06)](https://vznjs.github.io/vx/design/runtime-inputs-2026-06.md): A task's cache key today is derived from declared files, env-var - [A Rust rewrite — feasibility](https://vznjs.github.io/vx/design/rust-feasibility-2026-09.md): A first pass ran on Bun 1.3.11, which is below engines.bun. That - [Security review — 2026-07](https://vznjs.github.io/vx/design/security-review-2026-07.md): A 15-agent adversarial sweep across five attack surfaces (cache artifact - [The shared store (2026-10-06)](https://vznjs.github.io/vx/design/shared-store-2026-10.md): Owner ask (2026-10-05): "global cache in home folder like Nx in order to - [The site, redone as one story (2026-09-24, owner)](https://vznjs.github.io/vx/design/site-redo-2026-09.md): The owner's verdict on the site after track W: "Website is very bad. I - [The site, short (owner, 2026-09-24)](https://vznjs.github.io/vx/design/site-short-2026-09.md): The owner, after the Guide shipped: "The website is still terrible. It - [The site teaches (2026-09-23, roadmap track W)](https://vznjs.github.io/vx/design/site-teaches-2026-09.md): The owner asked for this on 2026-09-23: redo the site so it teaches what - [A streaming remote cache seam (2026-09-23, roadmap 2.2)](https://vznjs.github.io/vx/design/streaming-remote-2026-09.md): disk-backed stub: peak RSS +495 MiB over the round trip before, +45 MiB - [Per-task logs + artifacts in the dashboard — design](https://vznjs.github.io/vx/design/task-logs-2026-07.md): telemetry records are defined, versioned, and opt-in via TelemetrySink.wants - [Turbo / Nx parity: behavioural contracts vx does not pin (2026-07)](https://vznjs.github.io/vx/design/turbo-nx-parity-2026-07.md): Two independent research passes, run 2026-07-28 against the current upstream - [Turbo / Nx test-suite survey (2026-09-10)](https://vznjs.github.io/vx/design/turbo-nx-survey-2026-09.md): The owner's ask: "go through all tests of nx and turbo, see if we miss - [Turbo + Nx test gap analysis](https://vznjs.github.io/vx/design/turbo-nx-test-gaps.md): Generated: 2026-05-17. Source enumeration of ~205 Turbo tests (Rust unit + Cucumber-style .t integration fixtures across turborepo-task-hash,… - [Versioning and support (2026-09-23, roadmap 3.1–3.4)](https://vznjs.github.io/vx/design/versioning-10.md): This page says what a vx release may change, and what it may not. It - [vx on Windows (2026-09-28, stream O)](https://vznjs.github.io/vx/design/windows-2026-09.md): native code paths were removed on 2026-10-02 (owner); vx spawns sh -c - [Execution flows, scenario by scenario](https://vznjs.github.io/vx/flows.md): Companion to execution.md (prose lifecycle) and - [Internals (for contributors)](https://vznjs.github.io/vx/internals.md): How vx is built inside, for the people who change it — the technical overview, the architecture, the module reference and the design notes. - [Module reference](https://vznjs.github.io/vx/modules.md): One markdown per module under src/; a slice or helper is documented - [src/orchestrator/admission.ts — dedup and taint between scheduler and task](https://vznjs.github.io/vx/modules/admission.md): The scheduler hands run() a ready task; executeTask runs it. Two - [src/workspace/affected.ts — git-relative project selection](https://vznjs.github.io/vx/modules/affected.md): Power --affected[=base] and the [since] filter form. Resolves - [src/orchestrator/affected-tasks.ts — the tasks --affected reaches](https://vznjs.github.io/vx/modules/affected-tasks.md): (affectedChanges, affected.md) seeds tasks: - [src/bin.ts — binary entry point](https://vznjs.github.io/vx/modules/bin.md): The shebang script invoked when the user runs vx. Forwards - [cache.ts — content-addressed task cache](https://vznjs.github.io/vx/modules/cache.md): Compute cache keys, store cache entries, retrieve them, restore output - [src/cache/chained-cache.ts — several declared cache layers, in order](https://vznjs.github.io/vx/modules/chained-cache.md): When more than one plugin contributes a cache layer, resolveCache - [src/cli/index.ts — top-level command dispatcher](https://vznjs.github.io/vx/modules/cli.md): Argv → subcommand dispatch; the cli module's contract. Hand-rolled - [src/cli/cache.ts — vx cache prune](https://vznjs.github.io/vx/modules/cli-cache.md): Implements vx cache prune. Both parsers are util/size.ts's, - [src/cli/format.ts — shared formatters](https://vznjs.github.io/vx/modules/cli-format.md): Small string formatters shared by multiple CLI subcommands. The one - [src/cli/help.ts — help text](https://vznjs.github.io/vx/modules/cli-help.md): Static help text printed by vx help, vx --help, vx -h and a bare - [src/cli/run.ts — vx run parser + handler](https://vznjs.github.io/vx/modules/cli-run.md): Parse vx run's argv, resolve the run's options, and invoke the - [src/cli/watch.ts — vx watch subcommand (and watch-fs.ts, watch-filter.ts, watch-set.ts, watch-judge.ts, watch-cycle.ts)](https://vznjs.github.io/vx/modules/cli-watch.md): Run a task once, then re-run it on every filesystem change in the - [src/orchestrator/colors.ts — ANSI color gate](https://vznjs.github.io/vx/modules/colors.md): Decide whether to emit color and provide a single paint(color, - [src/config.ts — the public schema](https://vznjs.github.io/vx/modules/config.md): The single source of truth for what users can write in vx.config.ts. - [src/workspace/config-cache.ts — config evaluation cache](https://vznjs.github.io/vx/modules/config-cache.md): Skip re-evaluating a vx.config whose result cannot have changed. A - [src/workspace/config-imports.ts — the config-import selection channel](https://vznjs.github.io/vx/modules/config-imports.md): Answer one question for --affected: which projects' vx.config. - [src/workspace/config-schema.ts — what a config may say](https://vznjs.github.io/vx/modules/config-schema.md): The schema validators for vx.config. and vx.workspace.: every - [src/orchestrator/deferred-outputs.ts — the deferred-output registry](https://vznjs.github.io/vx/modules/deferred-outputs.md): Run-scoped home for tasks whose outputs were left in the remote store - [src/graph/dependency-spec.ts — Turbo/Nx micro-syntax parser](https://vznjs.github.io/vx/modules/dependency-spec.md): Parse one entry from dependsOn or cache.inputs.tasks into a small - [orchestrator/doctor.ts — the workspace doctor's facts](https://vznjs.github.io/vx/modules/doctor.md): One collector for what vx info prints and what @vzn/vx-mcp's - [src/orchestrator/download-policy.ts — --download modes + the deferral gate](https://vznjs.github.io/vx/modules/download-policy.md): Decides, ONCE per task at plan time, whether a remotely-executed task's - [src/exec/env.ts — child process env builder](https://vznjs.github.io/vx/modules/env.md): Compose the env object passed to every child process. Implements the - [src/orchestrator/events.ts — run event bus + wire contract](https://vznjs.github.io/vx/modules/events.md): renderer is just the always-on subscriber. An embedder attaches as - [src/orchestrator/excluded-keys.ts — keying a dependency that does not run](https://vznjs.github.io/vx/modules/excluded-keys.md): dependant's key folds its dependencies' keys (caching.md step 10), - [src/orchestrator/execute-task.ts — per-task runtime](https://vznjs.github.io/vx/modules/execute-task.md): The seam between the scheduler and the cache + runner. Given one - [src/exec/executor.ts — the per-task execution contract](https://vznjs.github.io/vx/modules/executor.md): The seam between "what to run" and "where it runs". execute-task.ts - [src/workspace/filter.ts — --filter DSL](https://vznjs.github.io/vx/modules/filter.md): Implement the pnpm-style filter language used by vx run --filter pattern. - [src/workspace/fingerprint.ts — workspace fingerprint](https://vznjs.github.io/vx/modules/fingerprint.md): Compute a single hash for the workspace as a whole, folded into every - [src/orchestrator/fingerprint-watch.ts — has a task rewritten the lockfile?](https://vznjs.github.io/vx/modules/fingerprint-watch.md): The workspace fingerprint (fingerprint.md) is read - [src/orchestrator/framed-output.ts — Turbo-style framed blocks](https://vznjs.github.io/vx/modules/framed-output.md): Format the per-task framed output block and the two compact one-liners - [src/cache/git-inputs.ts — git-backed input enumeration](https://vznjs.github.io/vx/modules/git-inputs.md): Talk to git once per run and turn the answer into what the resolver - [src/orchestrator/history.ts — per-task duration history](https://vznjs.github.io/vx/modules/history.md): A per-run, read-only HistoryTable snapshot: each (project, task) - [src/orchestrator/hit-restore.ts — what a hit leaves behind](https://vznjs.github.io/vx/modules/hit-restore.md): A confirmed cache entry, materialised: decide whether the tree is - [src/cache/inputs.ts — input/output glob resolution + cleaning](https://vznjs.github.io/vx/modules/inputs.md): Turn a task's declared cache.inputs into concrete data the cache key - [src/orchestrator/keyed-projects.ts — the projects a key answers for](https://vznjs.github.io/vx/modules/keyed-projects.md): K(T) in docs/design/linked-sibling-reads-2026-09.md: for a task, the - [src/exec/kill-tree.ts — a task dies with everything it forked](https://vznjs.github.io/vx/modules/kill-tree.md): Every task child is spawned detached — its own session and process - [src/cache/layered-cache.ts — local + remote cache composition](https://vznjs.github.io/vx/modules/layered-cache.md): Wraps the local Cache with a RemoteCacheLayer — the plugin seam - [src/orchestrator/local-shortcircuit.ts — restore-ahead classify](https://vznjs.github.io/vx/modules/local-shortcircuit.md): The up-front CLASSIFY behind the two-tier scheduler: derive every - [src/workspace/lockfile.ts — vx-lock.json](https://vznjs.github.io/vx/modules/lockfile.md): check of its own); vx lock --check reports changed files from the - [src/orchestrator/lockfile-claim.ts — the claimant's shell](https://vznjs.github.io/vx/modules/lockfile-claim.md): What every lockfile plugin needs around its parser. A plugin that keys - [src/orchestrator/logger.ts — pluggable logging surface](https://vznjs.github.io/vx/modules/logger.md): Provide a small Logger interface that the orchestrator + scheduler - [src/orchestrator/metrics.ts — run-history queries](https://vznjs.github.io/vx/modules/metrics.md): Pure functions over the run-history tables (runs, invocations, - [src/workspace/migration.ts — the plan → files seam](https://vznjs.github.io/vx/modules/migration.md): What any adoption tool needs once it has decided what a package's tasks - [src/orchestrator/miss-reason.ts — what a miss's key changed](https://vznjs.github.io/vx/modules/miss-reason.md): A telemetry sink wants to say why a task ran: "rebuilt because a source file changed". vx why answers that after a run, from the run - [src/orchestrator/miss-save.ts — what a miss leaves behind](https://vznjs.github.io/vx/modules/miss-save.md): Once a cached task's command exited 0 and the task will save, one call - [src/workspace/nested-dirs.ts — project-boundary set](https://vznjs.github.io/vx/modules/nested-dirs.md): For each project, compute the set of other projects' directories that - [src/orchestrator/options.ts — RunOptions / RunSummary](https://vznjs.github.io/vx/modules/options.md): The declaration home for the orchestrator's input/output types. They - [src/orchestrator/{index,run}.ts — end-to-end glue](https://vznjs.github.io/vx/modules/orchestrator.md): Placement — which executor each task lands on, and the --dry view of - [src/workspace/package-graph.ts — workspace dep graph](https://vznjs.github.io/vx/modules/package-graph.md): Build the workspace-internal dependency graph from each project's - [src/orchestrator/placement.ts — where each task runs](https://vznjs.github.io/vx/modules/placement.md): The placement of a task graph over the resolved executors, and the - [src/orchestrator/plan.ts — --dry / --graph planning](https://vznjs.github.io/vx/modules/plan.md): Walk the task graph, compute every task's cache key, and probe the - [src/cli/plan-format.ts — plan → text / JSON / DOT](https://vznjs.github.io/vx/modules/plan-format.md): Format a RunPlan (from plan.md) into one of three - [src/orchestrator/plugin.ts — the VxPlugin interface + installer](https://vznjs.github.io/vx/modules/plugin.md): The integration seam. A plugin is definePlugin(import.meta, hooks) - [src/cli/plugin-commands.ts — plugin-contributed CLI verbs](https://vznjs.github.io/vx/modules/plugin-commands.md): The commands seam's host. The dispatcher (cli/index.ts) matches - [src/orchestrator/plugin-host.ts — capability consultation](https://vznjs.github.io/vx/modules/plugin-host.md): Runs the pipeline stages: config, project and graph, where each - [Plugins — core ships none](https://vznjs.github.io/vx/modules/plugins.md): Core applies NO plugin on its own and ships none. Running a command - [src/orchestrator/prepare.ts — shared run/planRun setup](https://vznjs.github.io/vx/modules/prepare.md): discovery → config-load → graph-build → cache-open sequence before - [src/exec/proc-sample.ts — what a running task's processes use now](https://vznjs.github.io/vx/modules/proc-sample.md): wants a task's CPU and memory over its run (task.sample, telemetry.md) - [src/workspace/project-loader.ts — config file evaluation](https://vznjs.github.io/vx/modules/project-loader.md): Evaluate a vx.config.{ts,mts,js,mjs,cts,cjs} file and return the resolved - [src/orchestrator/projects.ts — the project-config load](https://vznjs.github.io/vx/modules/projects.md): One code path for "which tasks exist, resolved": prepareRun (a run, - [src/index.ts — public package surface](https://vznjs.github.io/vx/modules/public-surface.md): The single entry point for import x from '@vzn/vx'. Everything in - [src/orchestrator/remote-prefetch.ts — background remote GETs](https://vznjs.github.io/vx/modules/remote-prefetch.md): With a LayeredCache, remote GET latency would sit on each task's - [src/orchestrator/run-artifacts.ts — --summarize + --profile writers](https://vznjs.github.io/vx/modules/run-artifacts.md): Write the two optional run artifacts: - [src/orchestrator/run-context.ts — git/CI/host capture](https://vznjs.github.io/vx/modules/run-context.md): The per-run context for the invocations header row and the telemetry - [src/orchestrator/run-report.ts — markdown run report](https://vznjs.github.io/vx/modules/run-report.md): per-task table + totals line rendered after the run, machine-clean for - [src/exec/runner.ts — child process invocation + rusage capture](https://vznjs.github.io/vx/modules/runner.md): Spawn a shell command, stream stdout/stderr live, capture a bounded - [src/orchestrator/sandbox-request.ts — the sandbox half of a request](https://vznjs.github.io/vx/modules/sandbox-request.md): What a sandboxed task may read and write, where denials are reported, - [src/exec/sandbox-runtime.ts — sandbox wrapper for per-task isolation](https://vznjs.github.io/vx/modules/sandbox-runtime.md): Thin wrapper around @anthropic-ai/sandbox-runtime (SRT) for running a - [src/graph/scheduler.ts — two-tier parallel topological executor](https://vznjs.github.io/vx/modules/scheduler.md): Walk the task graph honoring dependencies, running up to N tasks - [src/orchestrator/signals.ts — a signal reaches every child](https://vznjs.github.io/vx/modules/signals.md): A SIGINT, SIGTERM or SIGHUP to the vx process mid-run forwards the - [src/orchestrator/stable-keys.ts — shared stable-key derivation](https://vznjs.github.io/vx/modules/stable-keys.md): Identifies tasks whose cache key is provably independent of any - [orchestrator/status-line.ts — dynamic worker region](https://vznjs.github.io/vx/modules/status-line.md): The live status display for interactive runs. Not a TUI: a - [src/orchestrator/summary.ts — end-of-run summary lines](https://vznjs.github.io/vx/modules/summary.md): Format the closing footer block — this is the run's only banner. - [src/orchestrator/tally.ts — shared outcome tally](https://vznjs.github.io/vx/modules/tally.md): Both the end-of-run terminal summary (summary.ts:formatRunSummary) - [src/graph/task-graph.ts — task DAG construction + cycle detection](https://vznjs.github.io/vx/modules/task-graph.md): Take the set of requested (project, task) pairs and a workspace - [src/orchestrator/task-hash.ts — cache-key derivation](https://vznjs.github.io/vx/modules/task-hash.md): The single place that selects and assembles the parts of a task's - [src/orchestrator/task-log-buffer.ts — bounded per-task log capture](https://vznjs.github.io/vx/modules/task-log-buffer.md): The one bounded-tail buffer a telemetry sink uses to capture task - [src/orchestrator/telemetry.ts — canonical telemetry export contract](https://vznjs.github.io/vx/modules/telemetry.md): THE versioned, serializable contract every telemetry consumer speaks - [src/orchestrator/telemetry-host.ts — telemetry capability consultation](https://vznjs.github.io/vx/modules/telemetry-host.md): Sibling of plugin-host.ts for the observe-only telemetry capability: - [src/util/timing.ts — VX_TIMING stage table](https://vznjs.github.io/vx/modules/timing.md): Answer "where did the warm run go?" without a profiler. With - [src/cli/upgrade.ts — self-update](https://vznjs.github.io/vx/modules/upgrade.md): and the SHA-256 digest the API publishes for it, downloads the asset, - [src/orchestrator/upstream.ts — upstream selection](https://vznjs.github.io/vx/modules/upstream.md): Answer two related questions about a task's dependencies, which are - [src/util/bun-version.ts — the runtime floor, read at run time](https://vznjs.github.io/vx/modules/util-bun-version.md): that; a RUN never reads it. bun src/bin.ts on an older Bun starts fine and - [util/cgroup.ts — the machine as this process may use it](https://vznjs.github.io/vx/modules/util-cgroup.md): Inside a container navigator.hardwareConcurrency and os.totalmem() - [src/util/edit-distance.ts — the one "did you mean" rule](https://vznjs.github.io/vx/modules/util-edit-distance.md): Every near-miss hint core prints — task names, pkg#task halves, - [src/util/errors.ts — clean error reporting](https://vznjs.github.io/vx/modules/util-errors.md): Distinguish user-input failures (config errors, missing refs, malformed - [src/util/hangup.ts — did vx start with SIGHUP ignored](https://vznjs.github.io/vx/modules/util-hangup.md): it with SIGHUP ignored. A process.on('SIGHUP') replaces that - [src/util/hash.ts — xxHash3 helpers](https://vznjs.github.io/vx/modules/util-hash.md): Thin wrappers over Bun.hash.xxHash3 shared by every cache-key - [src/util/num.ts — integers at the boundaries](https://vznjs.github.io/vx/modules/util-num.md): The numeric rules every argument boundary shares, and the one duration format every surface prints, in one place. - [src/util/paths.ts — POSIX-path normalisation](https://vznjs.github.io/vx/modules/util-paths.md): Normalize path separators to forward slashes so a path in a cache key - [src/util/procfs.ts — is /proc this process's view](https://vznjs.github.io/vx/modules/util-procfs.md): Two readers look other processes up by pid in /proc: the group - [src/util/real-path.ts — a path's canonical spelling](https://vznjs.github.io/vx/modules/util-real-path.md): One canonical spelling per path, so a key that folds a path and a - [src/util/secret-mask.ts — masking secret-named values in what vx shows](https://vznjs.github.io/vx/modules/util-secret-mask.md): A task that echoes $NPMTOKEN, or a TS config that builds its command - [src/util/settle.ts — the end-of-run settle bound](https://vznjs.github.io/vx/modules/util-settle.md): A plugin's flush or teardown is I/O a third party wrote; it must not - [src/util/tail.ts — head-evicting tail for a stream that may never end](https://vznjs.github.io/vx/modules/util-tail.md): A persistent task (dev server, watcher, daemon) is unbounded by - [src/util/ulid.ts — run-id generator](https://vznjs.github.io/vx/modules/util-ulid.md): Stamp every vx run invocation with a sortable, collision-resistant - [src/util/which.ts — a tool's absolute path, found once](https://vznjs.github.io/vx/modules/util-which.md): A spawn of a bare name makes Bun walk PATH with a stat per entry. vx - [src/version.ts — the VERSION constant](https://vznjs.github.io/vx/modules/version.md): A one-export leaf holding the package version string. Extracted from - [src/workspace/workspace.ts — workspace discovery](https://vznjs.github.io/vx/modules/workspace.md): Package globs come from the package manager's manifest and take its - [Optimization catalog](https://vznjs.github.io/vx/optimizations.md): Every performance decision that shipped, in one place: what it is, - [@vzn/vx — technical documentation](https://vznjs.github.io/vx/overview.md): vx is a task runner and content-addressed build cache for JavaScript - [Parity map for Turbo and Nx users](https://vznjs.github.io/vx/parity.md): What a Turborepo or Nx user relies on, the vx spelling of it, and the - [Shared patterns with Turborepo and Nx](https://vznjs.github.io/vx/patterns.md): The companion to comparison.md. That doc lists - [Upstream bug ledger](https://vznjs.github.io/vx/upstream-ledger.md): Real Turborepo and Nx bug reports in vx's scope, each checked against vx