Skip to content
Latest stable: v0.8.0.

Core API

The core package owns config validation, the seeded PRNG, event emission, presets, and the browser-side chaos engine used by every adapter.

export {
ChaosMaker,
ChaosConfigError,
validateChaosConfig,
validateConfig,
prepareChaosConfig,
VALIDATOR_BRAND_VERSION,
ChaosEventEmitter,
ChaosConfigBuilder,
presets,
PresetRegistry,
BUILT_IN_PRESETS,
expandPresets,
ProfileRegistry,
BUILT_IN_PROFILES,
applyProfile,
MatcherRegistry,
resolveNamedMatchers,
createPrng,
generateSeed,
formatSeedReproduction,
buildChaosReport,
formatReportJson,
formatReportMarkdown,
formatReportHtml,
classifyTransport,
filterEventsByTransport,
SW_BRIDGE_SOURCE,
};

validateChaosConfig(input, opts?) is the canonical structured validation entry - see Rule Validation for the full pipeline. validateConfig (schema-only, no preset or profile resolution) and prepareChaosConfig (Zod pass 1 + profile resolution + preset expansion + Zod pass 2, no brand or custom validators) remain available for advanced use.

class ChaosMaker {
constructor(config: ChaosConfig);
start(): void;
stop(): void;
getSeed(): number;
getLog(): ChaosEvent[];
clearLog(): void;
on(type: ChaosEventType | '*', listener: ChaosEventListener): void;
off(type: ChaosEventType | '*', listener: ChaosEventListener): void;
}

Most users should call a framework adapter instead of constructing ChaosMaker directly.

function createPrng(seed?: number): { random: () => number; seed: number };
function generateSeed(): number;

generateSeed() is the only intentional Math.random() use in core. All chaos decisions use createPrng(seed).random.

const config = new ChaosConfigBuilder()
.failRequests('/api/orders', 503, 1)
.withSeed(42)
.withDebug() // toggle Debug Mode on this config
.build();

withDebug(enabled = true) flips ChaosConfig.debug. See Debug Mode for the event taxonomy and console output format.

class ProfileRegistry {
constructor(initial?: Iterable<Profile>);
register(profile: Profile): void;
registerAll(entries: Record<string, ProfileConfigSlice> | undefined): void;
has(name: string): boolean;
get(name: string): ProfileConfigSlice;
list(): string[];
}
function applyProfile(config: ChaosConfig, registry: ProfileRegistry): ChaosConfig;
const BUILT_IN_PROFILES: ReadonlyArray<Profile>; // length 2: mobileCheckout + mobile-checkout alias

The registry is seeded by default with the single built-in mobileCheckout demo profile (plus its kebab alias mobile-checkout). applyProfile() is pure functional - same (config, registry) produces the same flattened output. prepareChaosConfig runs it between Zod pass 1 and preset expansion; the returned config has profile, profileOverrides, and customProfiles stripped.

Builder chain methods:

const config = new ChaosConfigBuilder()
.defineProfile('team-saturday-deploy', {
presets: ['flaky-api'],
network: { failures: [{ urlPattern: '/api/payments', statusCode: 503, probability: 0.3 }] },
})
.useProfile('team-saturday-deploy')
.overrideProfile({ seed: 42 })
.build();

.useProfile(name) is singular - a second call replaces the previously set name. .defineProfile(name, slice) rejects duplicate names within the builder. .overrideProfile(slice) accumulates across calls: rule arrays append, scalars (seed, debug) use last-write-wins. See Scenario profiles for the precedence table and the full surface.

interface MatcherEntry {
readonly name: string;
readonly config: NamedMatcher;
}
class MatcherRegistry {
constructor(initial?: Iterable<MatcherEntry>);
register(entry: MatcherEntry): void;
registerAll(entries: Record<string, NamedMatcher> | undefined): void;
has(name: string): boolean;
get(name: string): NamedMatcher;
list(): string[];
}
function resolveNamedMatchers(config: ChaosConfig, registry: MatcherRegistry): ChaosConfig;

MatcherEntry is the seed shape for MatcherRegistry: name normalizes via trim(), config is a NamedMatcher. The same shape is what register(entry) accepts. registerAll(record) is a convenience over a Record<string, NamedMatcher> (used by prepareChaosConfig to seed from ChaosConfig.matchers). ChaosConfigBuilder.defineMatcher(name, matcher) lands on the same registry path.

The registry seeds from ChaosConfig.matchers (no built-ins). resolveNamedMatchers() walks every network rule, inlines the registered fields into rules with a matcher reference, deletes the reference, and stamps the matcher name onto an internal WeakMap so buildRuleIdMap can surface matcherName on debug events. prepareChaosConfig runs the resolver last, after Zod pass 2.

Builder chain method:

const config = new ChaosConfigBuilder()
.defineMatcher('customers', { urlPattern: '/api/customers', methods: ['GET'] })
.build();

.defineMatcher(name, matcher) rejects duplicate names within the builder. Collisions against entries registered through ChaosConfig.matchers surface as matcher_collision at engine init. See Advanced matchers for the full surface, including the four issue codes (matcher_not_found, matcher_collision, matcher_inline_conflict, matcher_cycle) and the matcher attribution carried on debug events.

import { installChaosSW } from '@chaos-maker/core/sw';
installChaosSW({ source: 'message' });

The main package also exports SW_BRIDGE_SOURCE for adapters. Most users should prefer adapter helpers such as injectSWChaos() instead of calling the bridge directly.