Every feature
Every user-facing feature of vx, one line each, grouped by what it is for. Each line names its surface (verb, flag, config key, plugin), links its page on the site’s Features hub when it has one, and its blog post, or says “no post” when the story is still owed.
Rule: a change that adds or changes a user-facing feature updates
this file, and its post, in the same commit (CLAUDE.md).
tests/features-inventory.unsafe.test.ts fails when a CLI verb, a flag, a
config key or an environment variable is missing here.
- Run a task (
vx run) — run a task in the cwd’s project,pkg#taskdirectly, or several at once. page · post: The basics, done carefully - Every project (
--all) — run the task in every project that declares it. page · post: The basics, done carefully - pnpm-style filters (
--filter) — select projects by name, glob, path, dependencies (foo...), dependents (...foo), negation or a git range. page · post: Say exactly which tasks to run - Affected only (
--affected,affectedBase) — run what a change reaches, following task edges from a git base. page · post: Run only what a change reaches - Concurrency (
--concurrency,concurrency) — a count or a share of the CPUs this process may use (50%). page · post: One failure, and exactly what it takes down - Skip dependencies (
--exclude-dependencies) — skip alldependsOnedges, or named ones. page · post: Say exactly which tasks to run - Failure policy (
--continue) — never, deps-ok (default: dependents skip) or always. page · post: One failure, and exactly what it takes down - Every skip names its blocker — a skipped task says which failure blocked it. page · post: One failure, and exactly what it takes down
- Retries (
--retry,exec.retries) — re-run a failed task; a pass after a failure marks it flaky. page · post: Flaky is a claim only declared inputs can back - Timeouts (
--timeout,exec.timeout,timeout,VX_TASK_TIMEOUT) — kill and fail a runaway task. page · post: When a task misbehaves - Argument forwarding (
--) — args after--reach the task’s command and fold into its key. page · post: When a task misbehaves - Task picker —
vx runwith no task in a terminal lists tasks to pick. page · post: The small things - Typo hints — an unknown task, project or filter suggests the nearest name. page · post: The small things
- Turbo and Nx spellings (
-t,-p,--exclude,--parallel,--base,--dry-run,--skip-nx-cache) — accepted, or refused naming the vx spelling. page · post: Flags you already know - Ctrl-C leaves nothing running (
VX_KILL_GRACE_MS,VX_TEARDOWN_TIMEOUT_MS) — the whole process tree stops, then teardown runs. page · post: Ctrl-C leaves nothing running - Longest chain first — the scheduler starts the critical path first;
@vzn/vx-schedule-historylearns it from past runs. page · post: Bitsets, popcount, and a scheduler tick - No daemon — every run starts cold and still answers in milliseconds. page · post: No daemon, on purpose
- Group tasks (
dependsOnwith noexec) — a task that only runs its dependencies;dependsOn: []is a named no-op. page · post: Say exactly which tasks to run - Keyed groups (
cachewith noexec) — a key a dependant folds: it re-runs on those inputs, and nothing spawns or counts for the group. page · post: A key with nothing to run - Implicit keyed
build— a project with nobuildgets a^buildgroup keyed on its files, so source-only packages still move their dependants’ keys. page · post: The basics, done carefully - dependsOn syntax (
^name,pkg#name,name.*,^name.*) — upstream, cross-project and pattern edges. page · post: Say exactly which tasks to run - Every name must resolve —
vx run lint test typecheckrefuses to start if one name matches no project. page · post: Say exactly which tasks to run - Tag filters (
--filter tag:<pattern>) — select projects by their configtags. page · post: Say exactly which tasks to run - Directory and root filters (
./<dir>,{<dir>},.,//) — select projects by path, or the root project. page · post: Say exactly which tasks to run - Executor pools (executor
capacity) — a remote pool is admitted against its own width, not the laptop’s cores. page · post: Remote execution without moving the scheduler - Runs take turns — two vx runs on one workspace wait on a lock and name who they wait for. page · post: When a task misbehaves
Output
Section titled “Output”- Framed output — each task’s log in its own frame, never interleaved. page · post: A run you can read
- Output modes (
--output-logs) — full, errors-only, hash-only or none; the default follows the flow. page · post: Output that fits the run - Run summary — one block: projects, tasks, cache, time; nothing prints below it. page · post: A run you can read
- Per-task table (
--verbosity) — a per-task summary after the run. page · post: One failure, and exactly what it takes down - Failed output kept for agents — a failure’s full log is saved and pointed to. page · post: Built for the agent at the keyboard
- Markdown report (
--report,--report-file) — a run report for a PR or$GITHUB_STEP_SUMMARY. page · post: Output that fits the run - Run JSON (
--summarize) — per-run JSON for scripts, with the time the cache saved (savedMs). page · post: See inside a run - Trace profile (
--profile) — Chrome-trace JSON of the run. page · post: Output that fits the run - Run tags (
--tag) — label a run; recorded in history. page · post: See inside a run - Stage timing (
VX_TIMING) — vx’s own stage table, for performance work. page · post: See inside a run - Output flows — what is printed follows the run’s intent (focused, broad or CI); a truthy
CIwins. page · post: Output that fits the run - Cache-aware glyphs — each task line’s glyph shows ran, fresh, restored locally or remotely, failed, skipped or persistent. page · post: Output that fits the run
- GitHub Actions log groups — on Actions, each task’s block folds in a
::group::with its outcome and time. page · post: The basics, done carefully - Colors (
NO_COLOR,FORCE_COLOR) — truecolor output, forced on or off by env. page · post: The basics, done carefully - Signal-named exits — a failure reads
exit 137, 128 + SIGKILL. page · post: When a task misbehaves - Plain output off a TTY — no live region, and a missing task lists tasks instead of opening the picker. page · post: The basics, done carefully
Plan and explain
Section titled “Plan and explain”- Dry run (
--dry) — the task graph and the predicted hits and misses, text or JSON (with the predicted wall time and its critical path), nothing runs. page · post: See the plan before you run it - Graph (
--graph) — the task graph as Graphviz DOT. page · post: See inside a run - vx why (
vx why,--run) — why a task re-ran, down to the file, env var or config that changed. page · post: Why did this re-run? - vx show (
vx show) — every project, a project’s or a task’s live resolved config. page · post: See what a task really is - vx last (
vx last,--list,--failed,--log) — replay a recorded run’s summary, list recent runs, or print one task’s output. page · post: The last run, on request - vx info (
vx info) — workspace doctor: versions, projects, cache size againstcacheRetention.maxSize. page · post: One command to know your workspace - JSON everywhere (
--format) —show,info,why,lastandcacheprint JSON for agents. page · post: Built for the agent at the keyboard - Run analytics in SQLite — every task’s time, CPU, peak memory and cache result, queryable with
sqlite3. page · post: Built for the agent at the keyboard - Stable error codes (
VX_E_…) — under--format jsona refusal is a JSON line on stdout with a code an agent branches on and adocslink to its fix (vx docs <code>offline). page · post: A refusal an agent can read - Shipped JSON Schemas (
@vzn/vx/schemas/) — every--format jsonshape has a schema, and stdout always parses. page · post: Built for the agent at the keyboard - Docs for agents (
llms.txt,llms-full.txt) — the whole site as markdown for coding agents. page · post: Built for the agent at the keyboard - vx docs (
vx docs,--limit) — search the CLI, config and cache reference offline; it ships inside vx. page · post: The reference, offline - Affected reasons (
--affected --dry) — each kept task says the changed file or the dependency chain that reached it, text or JSON. page · post: See inside a run - Agent skill (
skills/vx/SKILL.md) — an installable skill that teaches a coding agent to run, debug and query vx. page · post: Built for the agent at the keyboard
- Opt-in, explicit inputs (
cache.inputs.files) — a task caches only when it names its inputs. page · post: Explicit over magical - Inputs (
cache.inputs.env,cache.inputs.runtime,cache.inputs.tasks,cache.inputs.workspaceFiles,cache.inputs.workspaceRuntime) — env vars, tool versions, upstream tasks and workspace files in the key. page · post: What goes into a key, and what comes back - Outputs (
cache.outputs.files,cache.outputs.workspaceFiles) — what a hit restores. page · post: What goes into a key, and what comes back - Outputs are exactly the snapshot (
exclusiveOutputs) — a hit leaves the tree as the run did; two tasks may not own one output without an edge. page · post: The tree is exactly the snapshot - Keys from git’s index — tracked clean files hash by their blob id, no read. page · post: Your cache key is already in git’s index
- Config keyed as evaluated — the key sees the resolved config object. page · post: Configs are programs
- Cascade through inputs — a task’s key folds its upstream input keys, never outputs. page · post: Cascade through dependencies
- Lockfile-aware keys (
@vzn/vx-lockfile:pnpm(),bun(),npm(),yarn()) — a bump re-keys only the projects whose closure changed. page · post: A lockfile bump should re-key two tasks - Upfront keys (
upfrontKeys) — refuses an input glob a same-project task’s outputs could match, so every key is known before anything runs. page · post: Cascade through dependencies by folding input keys, never outputs - Cache controls (
--no-cache,--force,--cache) — off, refresh, or per-layer read/write. page · post: The cache on your terms - Cache location (
--cache-dir,cacheDir,VX_CACHE_DIR) — where the cache lives. page · post: The cache on your terms - Cache scope (
cacheScope,VX_CACHE_SCOPE) — trusted CI writes the remote cache; a laptop reads it. page · post: The cache on your terms - Cache pruning (
vx cache prune,--older-than,--max-size,--dry-run,cacheRetention,maxSize,olderThan) — evict by age or size, LRU. page · post: One command to know your workspace - Remote outputs (
--download) — all, top-level only, or none. page · post: A remote server you can trust in production - One store for every checkout (
~/.vx/<id>/cache) — clones and worktrees of a repo share cache entries. page · post: The cache on your terms - Warm hits restore nothing — when outputs on disk already match, a hit costs a few stats. page · post: What goes into a key, and what comes back
- Hits replay both streams — stdout and stderr come back in the order the run printed them. page · post: What goes into a key, and what comes back
- Restore lane — cache restores run on their own lane, up to twice
--concurrency. page · post: What goes into a key, and what comes back - Config evaluation cache — provably pure
vx.config.tsfiles are read back as data, not evaluated again. page · post: Guard rails that tell you the fix - Line-ending-correct keys — files git filters (
eol,core.autocrlf) key on the bytes the build sees. page · post: Your cache key is already in git’s index - Background remote uploads — remote writes drain at the end of the run and never fail the build. page · post: What goes into a key, and what comes back
- Bring your own remote cache (plugin
cache) — plug any cache server in through one interface. page · post: Extend vx in an afternoon
Correctness
Section titled “Correctness”- Sandboxed tasks (
exec.sandbox:allow,deny,ignore,weakerNetworkIsolation,weakerWhenNested) — a task reads and writes only what it declares;allownamesread,write,network,unixSockets,localBinding,pty,systemInfo,gitConfig,machLookup. page · post: The sandbox - Env isolation (
exec.env:define,passThrough,secret) — a task sees only the env it names; secrets are masked. page · post: A task sees only the env it names - vx lock (
vx lock,--check,--format json,--frozen) — freeze what configs evaluate to; CI and agents check it. page · post: vx lock: freezing what the key sees - Flaky detection — a task that fails then passes is reported flaky. page · post: Flaky is a claim
- Project boundaries — globs never cross into another project. page · post: What goes into a key, and what comes back
- Artifact integrity checks — a CRC-32, a key match and an outputs-only check on every artifact; damage is a miss. page · post: What goes into a key, and what comes back
- Sandbox names what to grant — a refused write is named beside the failed task with the path to allow. page · post: Guard rails that tell you the fix
- Strict numeric flags —
0x10,1e3and2.7are refused, never reinterpreted. page · post: An upgrade you can trust - Verified releases — binaries carry provenance,
vx upgradechecks SHA-256, npm publishes with provenance. page · post: An upgrade you can trust
Daily work
Section titled “Daily work”- Watch mode (
vx watch,VX_WATCH_POLL) — re-run what a change affects, on content, not events. page · post: Watch: a content gate - Dev servers in the graph (
exec.persistent,readyWhen,VX_READY_NOTICE_MS) — a server is a node; dependents start when it is ready. page · post: Dev servers as graph nodes - Interactive tasks (
exec.interactive) — a task that owns the terminal. page · post: When a task misbehaves - Shell completions (
vx completions) — bash, zsh, fish. page · post: The small things - vx upgrade (
vx upgrade) — replace the binary with a release. page · post: An upgrade you can trust - Help and version (
vx help,vx version) — every verb’s reference. page · post: An upgrade you can trust - Did-you-mean — a mistyped flag or verb gets the nearest valid spelling. page · post: The small things
- Task typed as a verb —
vx build appanswers with the exactvx runcommand that does it. page · post: The small things
Config
Section titled “Config”- Config in TypeScript (
vx.config.ts,defineProject,vx.workspace.ts,defineWorkspace) — typed, composable; no named inputs. page · post: Config in TypeScript - Tasks (
tasks,exec.command,dependsOn,description,tags) — one command per task; the shell is the API. page · post: One command per task - Workspace rules (
rules) — speed-only checks, on by default, configurable. page · post: Guard rails that tell you the fix - Config worker timeout (
VX_CONFIG_WORKER_TIMEOUT_MS) — bound a config’s evaluation. page · post: Guard rails that tell you the fix - No nested runs (
VX_RUN_TASK,VX_RUN_WORKSPACE) — set on every task; avx runinside a task of the same workspace is refused. page · post: When a task misbehaves - Typed config helpers (
defineProject) — autocomplete for task names independsOn, errors while you edit. page · post: Config in TypeScript, and why there are no named inputs - Presets — a TypeScript function returning a task config, shared across projects. page · post: Config in TypeScript, and why there are no named inputs
- Clean config errors — a bad config fails at load naming the key, with no stack trace. page · post: When a task misbehaves
- Results on GitHub (
@vzn/vx-ci:github()) — job summary and Checks API annotations. page · post: Your run, on the pull request - PR check run (
github({ checks })) — a check run on the commit with the run summary as its output. page · post: Your run, on the pull request - Cache scope from the ref (
github({ cacheScope })) — main writes trusted keys; a PR writes only its own scope. page · post: The cache on your terms
Adoption
Section titled “Adoption”- Start in a minute (
vx init,--dry,--format json,--force,--mjs) — writevx.workspace.tsand onevx.config.tsper package;--dry --format jsonhands an agent the plan as data. page · post: Hello, vx - Migrate from Turborepo or Nx (
vx init,--native,--keep,@vzn/vx-migrate) — native config, or keepturbo()/nx()as a start. page · posts: From Turborepo, From Nx - Keep a Turbo or Nx remote cache (
turboCache(),nxCache()) — reuse the cache server you have. page · post: From Nx: keep the graph, drop the platform - One binary — one file, nothing to install underneath. page · post: One binary
- The playground — vx’s planner in the browser. page · post: Try the planner in your browser
- Benchmarks you can re-run (
@vzn/vx-bench) — vx against Turborepo and Nx. page · posts: Benchmarks you can re-run, Why vx is fast - npm pre/post scripts —
pre<x>andpost<x>hooks fold intox’s command whenvx initmaps scripts. page · post: From npm scripts or Vite Task - Vite Task adoption (
bunx @vzn/vx-migrate) — writes configs from vite-plusrun.tasksas well as Turbo and Nx. page · post: From npm scripts or Vite Task - Nx executors as one process (
nx-exec) — any Nx executor runs as one vx task with its Nx env set. page · post: From Nx: keep the graph, drop the platform - Programmatic API (
run,planRun) — run or plan from your own scripts via@vzn/vx. page · post: Extend vx in an afternoon
Plugins
Section titled “Plugins”- A pipeline with seams (
plugins,definePlugin; stagesconfigdiscoverprojectgraphkeyfingerprintscheduleadmitexecutorcachetelemetrycommands) — every stage is a plugin seam. page · post: A pipeline with seams - Write a plugin (
vx init --plugin) — scaffold a runnable plugin for a seam. page · post: Extend vx in an afternoon - The local floor — running and caching here are core’s, not plugins. page · post: The local floor
- Remote cache and execution (
@vzn/vx-reapi,exec.remote) — Bazel REAPI cache and workers; the scheduler stays here. page · post: Remote execution without moving the scheduler - OpenTelemetry (
@vzn/vx-otel) — each run exported to your OpenTelemetry backend, never breaking it. page · post: Observability that cannot break a run - vx mcp (
@vzn/vx-mcp,vx mcp) — cache stats, run history,vx why’s full answer, a run tool (mcp({ run })limits it to named tasks or turns it off), a plan tool, a task’s resolved config, the lock audit, cache pruning, thevx initplan, an offline docs search and a task list narrowed by--filter/--affectedfor coding agents. page · post: Give your coding agent the build’s memory - vx prune (
@vzn/vx-lockfile,vx prune,--production) — copy projects and their deps, lockfile pruned, for a Docker build;--productionleaves out what only dev dependencies need. page · post: Ship one app, not the whole monorepo, A runtime image without the dev tools - vx history (
@vzn/vx-schedule-history,vx history) — what the scheduler learned per task. page · post: A scheduler that learns from your runs - Setup and teardown hooks (
setup,teardown) — plugin code around the run, bounded by a timeout. page · post: Extend vx in an afternoon - REAPI TLS, mTLS and headers — connect to hosted servers such as BuildBuddy the way Bazel does. page · post: A remote server you can trust in production
- REAPI execution records — a repeat remote execution skips the worker and replays outputs and stdout. page · post: A remote server you can trust in production
- REAPI verified downloads and deadlines — a corrupt blob or a wedged server degrades to a miss, never a hang. page · post: A remote server you can trust in production
- Install as a remote action (
exec.remote: 'only') —node_modulesis built by an action, so stateless workers have it. page · post: Remote execution without moving the scheduler - OTel live export (
otel({ live })) — spans and metrics stream as tasks end, so a dashboard follows a CI run live. page · post: Watch a CI run while it runs - Memory-aware admission (
@vzn/vx-schedule-history) — tasks are packed by the peak memory learned from past runs. page · post: A scheduler that learns from your runs