Standalone CLI
The vitiate CLI is the primary interface for fuzzing, regression testing, and corpus management. It provides subcommands for each workflow:
| Subcommand | Description |
|---|---|
vitiate fuzz | Run all fuzz tests with coverage-guided mutation |
vitiate regression | Replay saved corpus and crash inputs as regression tests |
vitiate optimize | Minimize cached corpus via set cover |
vitiate init | Discover fuzz tests and create seed directories |
vitiate libfuzzer | libFuzzer-compatible mode for platform integration |
Fuzzing
Section titled “Fuzzing”npx vitiate fuzzThis runs all *.fuzz.ts files with coverage-guided fuzzing. The fuzzer runs indefinitely until you press Ctrl+C, a crash is found, or a configured limit is reached.
Setting limits
Section titled “Setting limits”# Stop after 60 secondsnpx vitiate fuzz --fuzz-time 60
# Stop after 100,000 iterationsnpx vitiate fuzz --fuzz-execs 100000
# Collect at most 5 crashes then stopnpx vitiate fuzz --max-crashes 5
# Combine limits (whichever comes first)npx vitiate fuzz --fuzz-time 120 --max-crashes 3Selecting detectors
Section titled “Selecting detectors”The --detectors flag controls which bug detectors are active. When specified, all defaults are disabled and only the listed detectors run:
# Enable only prototype pollution detectionnpx vitiate fuzz --detectors prototypePollution
# Enable multiple detectorsnpx vitiate fuzz --detectors prototypePollution,pathTraversal
# Disable all detectorsnpx vitiate fuzz --detectors ""Forwarding flags to Vitest
Section titled “Forwarding flags to Vitest”Unrecognized flags are forwarded to Vitest. You can also use -- to pass flags explicitly:
# Forward a reporter flagnpx vitiate fuzz --reporter verbose
# Use -- separator for claritynpx vitiate fuzz -- --reporter verboseFlags reference
Section titled “Flags reference”| Flag | Description |
|---|---|
--fuzz-time <seconds> | Total fuzzing time limit in seconds |
--fuzz-execs <count> | Total number of fuzzing iterations |
--max-crashes <count> | Maximum crashes to collect |
--detectors <list> | Comma-separated list of bug detectors to enable |
Regression testing
Section titled “Regression testing”npx vitiate regressionRuns all *.fuzz.ts files as normal Vitest tests, replaying saved corpus entries and crash inputs without generating new mutations. This verifies that previously found bugs remain fixed and that the test targets still pass on known inputs.
The --detectors flag works the same as in vitiate fuzz. Unrecognized flags are forwarded to Vitest.
Corpus optimization
Section titled “Corpus optimization”npx vitiate optimizeMinimizes the cached corpus for all fuzz tests by evaluating each input’s coverage contribution and keeping only the smallest set that maintains the same total coverage. This reduces disk usage and speeds up future regression runs.
The --detectors flag works the same as in vitiate fuzz. Unrecognized flags are forwarded to Vitest.
Project setup
Section titled “Project setup”npx vitiate initDiscovers all *.fuzz.ts files, collects their fuzz() test names, and creates the seed directory structure under .vitiate/testdata/. It also adds .vitiate/corpus/ to .gitignore if not already present.
The output includes a manifest of discovered tests with their hash directories, which is useful for understanding the on-disk layout.
libFuzzer compatibility
Section titled “libFuzzer compatibility”The libfuzzer subcommand provides a libFuzzer-compatible interface for integration with fuzzing platforms like OSS-Fuzz and CI services that expect libFuzzer-style flags and conventions. Unlike the other subcommands, it targets a single test file and accepts positional corpus directories.
npx vitiate libfuzzer test/parser.fuzz.tsTargeting a specific test
Section titled “Targeting a specific test”If the file contains multiple fuzz() calls, target one by name:
npx vitiate libfuzzer test/parser.fuzz.ts -test "parse does not crash"Setting limits
Section titled “Setting limits”# Stop after 60 secondsnpx vitiate libfuzzer test/parser.fuzz.ts -max_total_time 60
# Stop after 100,000 iterationsnpx vitiate libfuzzer test/parser.fuzz.ts -runs 100000Corpus directories
Section titled “Corpus directories”Pass additional corpus directories as positional arguments after the test file:
npx vitiate libfuzzer test/parser.fuzz.ts corpus/ shared-corpus/The fuzzer loads inputs from these directories alongside the seed corpus and cached corpus.
Dictionaries and artifacts
Section titled “Dictionaries and artifacts”# Use a dictionary file with domain-specific tokensnpx vitiate libfuzzer test/parser.fuzz.ts -dict ./tokens.dict
# Override the crash artifact output locationnpx vitiate libfuzzer test/parser.fuzz.ts -artifact_prefix ./crashes/When using vitiate fuzz, place dictionary files directly in .vitiate/testdata/<hashdir>/ for automatic discovery instead. See Dictionaries and Seeds for details.
Merge mode
Section titled “Merge mode”The -merge 1 flag minimizes a corpus across arbitrary directories:
# Merge multiple corpus directories into a minimized setnpx vitiate libfuzzer test/parser.fuzz.ts -merge 1 minimized-corpus/ .vitiate/corpus/ extra-corpus/
# Replace the old corpus with the minimized onerm -rf .vitiate/corpus/mv minimized-corpus/ .vitiate/corpus/The first positional directory is the output; the rest are inputs. For integrated corpus minimization, use npx vitiate optimize instead.
Supervisor architecture
Section titled “Supervisor architecture”The CLI runs a supervisor (parent) process that manages crash recovery. When the worker process crashes, the supervisor reads the crashing input from shared memory, writes the crash artifact to disk, and spawns a new worker to continue fuzzing. This means the fuzzer is resilient to crashes and keeps going until you stop it or it hits a configured limit.
Compatibility flags
Section titled “Compatibility flags”All flags use the libFuzzer naming scheme (-max_total_time, -runs, -dict, etc.). The following flags are parsed for compatibility but ignored since they do not apply to Vitiate’s architecture:
| Flag | Behavior |
|---|---|
-fork | Parsed, ignored (always 1 - Vitiate uses a single supervised worker) |
-jobs | Parsed, ignored (always 1 - Vitiate runs a single job at a time) |
See the CLI Flags Reference for the complete list of libFuzzer-compatible flags.
Output format
Section titled “Output format”The fuzzer prints periodic status lines during execution:
fuzz: elapsed: 3s, execs: 1024 (3412/sec), corpus: 23 (5 new), edges: 142| Field | Meaning |
|---|---|
elapsed | Time since fuzzing started |
execs | Total executions so far (with per-second rate) |
corpus | Corpus size, with number of new entries since last status |
edges | Unique coverage edges discovered |
Environment variables
Section titled “Environment variables”The following environment variables configure Vitiate’s behavior. Where a CLI flag equivalent exists, the CLI flag takes precedence.
| Variable | Description | CLI flag equivalent |
|---|---|---|
VITIATE_FUZZ_TIME | Fuzzing time limit in seconds | --fuzz-time |
VITIATE_FUZZ_EXECS | Total number of fuzzing iterations | --fuzz-execs |
VITIATE_MAX_CRASHES | Maximum crashes to collect | --max-crashes |
VITIATE_FUZZ | Set to 1 to enable fuzzing mode (set automatically by vitiate fuzz) | - |
VITIATE_OPTIMIZE | Set to 1 to enable optimize mode (set automatically by vitiate optimize) | - |
VITIATE_DEBUG | Set to 1 to enable debug logging | - |
VITIATE_FUZZ and VITIATE_OPTIMIZE are mutually exclusive. The vitiate fuzz and vitiate optimize subcommands set these automatically - you typically only need to set them manually when invoking Vitest directly without the CLI.