Skip to content

Standalone CLI

The vitiate CLI is the primary interface for fuzzing, regression testing, and corpus management. It provides subcommands for each workflow:

SubcommandDescription
vitiate fuzzRun all fuzz tests with coverage-guided mutation
vitiate regressionReplay saved corpus and crash inputs as regression tests
vitiate optimizeMinimize cached corpus via set cover
vitiate initDiscover fuzz tests and create seed directories
vitiate libfuzzerlibFuzzer-compatible mode for platform integration
Terminal window
npx vitiate fuzz

This 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.

Terminal window
# Stop after 60 seconds
npx vitiate fuzz --fuzz-time 60
# Stop after 100,000 iterations
npx vitiate fuzz --fuzz-execs 100000
# Collect at most 5 crashes then stop
npx vitiate fuzz --max-crashes 5
# Combine limits (whichever comes first)
npx vitiate fuzz --fuzz-time 120 --max-crashes 3

The --detectors flag controls which bug detectors are active. When specified, all defaults are disabled and only the listed detectors run:

Terminal window
# Enable only prototype pollution detection
npx vitiate fuzz --detectors prototypePollution
# Enable multiple detectors
npx vitiate fuzz --detectors prototypePollution,pathTraversal
# Disable all detectors
npx vitiate fuzz --detectors ""

Unrecognized flags are forwarded to Vitest. You can also use -- to pass flags explicitly:

Terminal window
# Forward a reporter flag
npx vitiate fuzz --reporter verbose
# Use -- separator for clarity
npx vitiate fuzz -- --reporter verbose
FlagDescription
--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
Terminal window
npx vitiate regression

Runs 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.

Terminal window
npx vitiate optimize

Minimizes 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.

Terminal window
npx vitiate init

Discovers 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.

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.

Terminal window
npx vitiate libfuzzer test/parser.fuzz.ts

If the file contains multiple fuzz() calls, target one by name:

Terminal window
npx vitiate libfuzzer test/parser.fuzz.ts -test "parse does not crash"
Terminal window
# Stop after 60 seconds
npx vitiate libfuzzer test/parser.fuzz.ts -max_total_time 60
# Stop after 100,000 iterations
npx vitiate libfuzzer test/parser.fuzz.ts -runs 100000

Pass additional corpus directories as positional arguments after the test file:

Terminal window
npx vitiate libfuzzer test/parser.fuzz.ts corpus/ shared-corpus/

The fuzzer loads inputs from these directories alongside the seed corpus and cached corpus.

Terminal window
# Use a dictionary file with domain-specific tokens
npx vitiate libfuzzer test/parser.fuzz.ts -dict ./tokens.dict
# Override the crash artifact output location
npx 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.

The -merge 1 flag minimizes a corpus across arbitrary directories:

Terminal window
# Merge multiple corpus directories into a minimized set
npx vitiate libfuzzer test/parser.fuzz.ts -merge 1 minimized-corpus/ .vitiate/corpus/ extra-corpus/
# Replace the old corpus with the minimized one
rm -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.

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.

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:

FlagBehavior
-forkParsed, ignored (always 1 - Vitiate uses a single supervised worker)
-jobsParsed, ignored (always 1 - Vitiate runs a single job at a time)

See the CLI Flags Reference for the complete list of libFuzzer-compatible flags.

The fuzzer prints periodic status lines during execution:

fuzz: elapsed: 3s, execs: 1024 (3412/sec), corpus: 23 (5 new), edges: 142
FieldMeaning
elapsedTime since fuzzing started
execsTotal executions so far (with per-second rate)
corpusCorpus size, with number of new entries since last status
edgesUnique coverage edges discovered

The following environment variables configure Vitiate’s behavior. Where a CLI flag equivalent exists, the CLI flag takes precedence.

VariableDescriptionCLI flag equivalent
VITIATE_FUZZ_TIMEFuzzing time limit in seconds--fuzz-time
VITIATE_FUZZ_EXECSTotal number of fuzzing iterations--fuzz-execs
VITIATE_MAX_CRASHESMaximum crashes to collect--max-crashes
VITIATE_FUZZSet to 1 to enable fuzzing mode (set automatically by vitiate fuzz)-
VITIATE_OPTIMIZESet to 1 to enable optimize mode (set automatically by vitiate optimize)-
VITIATE_DEBUGSet 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.