Configuration

Customize FlakeMonster's behavior with a project-level config file. All settings are optional and have sensible defaults.

Config File Locations

FlakeMonster searches for a configuration file in your project root directory. Two file names are supported:

If both files exist, .flakemonsterrc.json takes precedence. Configuration is entirely optional — when no config file is found, FlakeMonster uses built-in defaults for every value.

Tip: Start without a config file. Add one only when you need to customize behavior for your specific project.

FlakeMonster resolves the config file from the current working directory. If you run the CLI from a subdirectory, it will not walk up parent directories to find a config file. Always run FlakeMonster from your project root, or pass settings via CLI flags.

Schema

The config file is a JSON object. Every field is optional. Here is the full schema:

File Selection

Field Type Default Description
include string[] ["src/**/*.js"] Glob patterns for files to inject delays into. Paths are relative to the project root.
exclude string[] ["**/node_modules/**", "**/dist/**", "**/build/**"] Glob patterns for files to skip. Matched files are excluded even if they match an include pattern.

Injection Settings

Field Type Default Description
mode string "medium" Injection density. Controls how many async call sites receive delays. One of: "light", "medium", "hardcore".
minDelayMs number 0 Minimum delay in milliseconds. The lowest value a generated delay can have.
maxDelayMs number 50 Maximum delay in milliseconds. The highest value a generated delay can have.
distribution string "uniform" Delay distribution algorithm. Controls how delay values are spread between minDelayMs and maxDelayMs.
skipTryCatch boolean false Reserved for a future release. When implemented, will skip injection inside try/catch blocks. Does not currently affect injection behavior.
skipGenerators boolean true When true, skips injection inside async generator functions. Enabled by default because injected delays between yields can cause unexpected iterator behavior or deadlocks in consumer code.

Test Runner Settings

Field Type Default Description
testCommand string "npm test" The shell command to run your test suite. Equivalent to --cmd on the CLI.
runs number 10 Number of times to run the test command, each with a different seed.
keepOnFail boolean true When true, keeps the workspace directory intact after a failure so you can inspect the injected code.

CLI Override Rules

FlakeMonster resolves configuration in three layers, from lowest to highest priority:

  1. Built-in defaults — hardcoded values shown in the schema tables above
  2. Config file — values from .flakemonsterrc.json or flakemonster.config.json
  3. CLI flags — flags passed directly on the command line

Each layer overrides the one below it. This means CLI flags always win.

Merge Behavior

Most fields use simple replacement: the higher-priority value replaces the lower one entirely. However, --exclude has special behavior:

Important: The --exclude CLI flag appends to the config file's exclude array rather than replacing it. This ensures the default exclusions (node_modules, dist, build) are never accidentally removed.

Example: Merge in action

Given this config file:

{
  "exclude": ["**/node_modules/**", "**/dist/**", "**/build/**"],
  "mode": "light",
  "runs": 5
}

And this CLI invocation:

$ npx flake-monster test --mode "hardcore" --exclude "**/vendor/**" --cmd "npm test"

The resolved configuration is:

Field Resolved Value Source
mode "hardcore" CLI flag overrides config
runs 5 Config file (no CLI override)
exclude ["**/node_modules/**", "**/dist/**", "**/build/**", "**/vendor/**"] Config + CLI appended
testCommand "npm test" CLI flag (--cmd)
minDelayMs 0 Built-in default

Examples

Minimal Config

Most projects only need to customize the include pattern and test command. Let defaults handle the rest:

// .flakemonsterrc.json
{
  "include": ["src/**/*.js"],
  "testCommand": "npm test"
}

Full Config

Every available option specified explicitly:

// .flakemonsterrc.json
{
  "include": ["src/**/*.js", "lib/**/*.js"],
  "exclude": ["**/node_modules/**", "**/dist/**", "**/build/**", "**/fixtures/**"],
  "mode": "medium",
  "minDelayMs": 0,
  "maxDelayMs": 50,
  "distribution": "uniform",
  "testCommand": "npm test",
  "runs": 10,
  "keepOnFail": true,
  "skipTryCatch": false,
  "skipGenerators": true
}

Playwright Project

End-to-end test suites with Playwright benefit from higher delays and more aggressive injection to surface timing-dependent failures:

// .flakemonsterrc.json
{
  "include": ["src/**/*.ts", "src/**/*.js"],
  "exclude": [
    "**/node_modules/**",
    "**/dist/**",
    "**/build/**",
    "**/playwright-report/**",
    "**/test-results/**"
  ],
  "mode": "hardcore",
  "minDelayMs": 5,
  "maxDelayMs": 200,
  "testCommand": "npx playwright test",
  "runs": 20,
  "keepOnFail": true,
  "skipTryCatch": true
}

The higher maxDelayMs of 200ms exaggerates timing differences that browser-based tests are sensitive to. Setting skipTryCatch to true avoids interfering with Playwright's built-in retry and timeout error handling. Running 20 iterations increases the chance of catching intermittent failures.

Monorepo

In a monorepo, place the config file in each package that should be fuzzed independently, or use a single config at the repo root with broader include patterns:

// .flakemonsterrc.json (repo root)
{
  "include": [
    "packages/api/src/**/*.js",
    "packages/web/src/**/*.js",
    "packages/shared/src/**/*.js"
  ],
  "exclude": [
    "**/node_modules/**",
    "**/dist/**",
    "**/build/**",
    "**/__mocks__/**"
  ],
  "mode": "light",
  "testCommand": "npm run test:all",
  "runs": 5
}

Using "light" mode in a monorepo keeps total injection time manageable across many packages. You can override with --mode medium on the CLI when investigating a specific flaky test. To fuzz a single package, narrow the scope with CLI flags:

$ npx flake-monster test --include "packages/api/src/**/*.js" --cmd "npm run test -w packages/api"