lara-zeus/chaos
Part of the Lara Zeus suite, Chaos is a Laravel package that speeds up building dynamic, data-driven applications with reusable utilities and sensible conventions that cut boilerplate and keep your codebase clean and maintainable.
Chaos is a fault-injection companion for the Lara Zeus/Filament ecosystem: it lets you make a healthy application behave badly on purpose so the error paths you already wrote — retries, fallbacks, user-facing messages, alerting — actually get exercised. Adopt it as a dev/staging-only dependency plus a habit, not as architectural plumbing.
Resolve the description ambiguity first. The package blurb describes a low-ceremony "wire Zeus components together" companion; the assessment material describes config-driven chaos rules, triggers, probability settings, and environment-aware safeguards. Those are different products with different integration costs. Spend ten minutes reading the tagged source, the published config, and tests/ (which gained Pest coverage in 3.0.7 and is the most reliable usage documentation) before you write any rules. The config file is the real public API surface.
Minimal steps:
composer require lara-zeus/chaos — Laravel package discovery registers the provider; no manual providers entry in a standard app. Keep it in require-dev if it stays out of deployed code paths.php artisan vendor:publish and select the Chaos entry rather than guessing the tag; if a tag exists, prefer --tag=chaos-config. Commit config/chaos.php so rules are reviewed like code.CHAOS_ENABLED=false) and confirm the package's own environment guard in the config. Ship false in .env.example; keep the key absent from production entirely.First use case, worth doing on day one: pick one outbound boundary — a single Http:: call to a third-party API, or one queued job that talks to an external service — and enable a low-probability failure rule against it. Then walk your own error path end to end: does the retry actually retry, does the fallback value render, does the job land in failed_jobs, does the user see a sane message instead of a stack trace? That one loop both validates whether the abstraction fits your codebase and audits error handling you have probably never exercised. Everything after is scaling the same loop.
Inject at boundaries, not in domain logic. Place injection where your app meets something it does not control: HTTP clients, queue dispatch, filesystem writes, cache, occasionally the DB. Chaos inside business rules produces failures that are hard to attribute and impossible to reason about.
Config is the rule set; code is the call site. Keep probabilities, environment allow-lists, and target selection in config/chaos.php so you can flip behaviour without a deploy. Each call site should be one line — easy to grep, easy to strip later.
Scope rules to a slice, not the whole app. Two developers with a global 20% failure rate locally will spend an afternoon blaming each other's branches. Scope by route, tenant, user ID, or a named scenario. A scenario (checkout-degraded, payment-timeout) that a developer opts into with a single env value beats a global dice roll, and it doubles as shared vocabulary in incident retros.
Make it reproducible. Probabilistic chaos in a test suite is a flaky-test generator. Use a fixed seed or a deterministic "always fail this rule" mode for tests and reserve genuine randomness for exploratory staging. "With rule X forced on, the endpoint returns 503 and the client retries twice" is valuable and stable; the same test at 30% probability is noise.
Wire it into CI as a second pass. Your normal suite runs with chaos off. Add one job running a targeted subset with chaos on and a fixed seed — retry, fallback, and idempotency tests specifically. That catches the class of bug that only appears when the second attempt succeeds after the first partially wrote.
Keep the package behind a thin seam. Wrap injection in your own small helper (a ChaosGuard-style class or trait) rather than sprinkling LaraZeus\Chaos\* references across the app. One indirection layer makes a version bump — or a swap to a hand-rolled App::environment() check plus a random integer — a single-file change. With zero dependents upstream, that is the cheapest insurance you can buy.
Pair it with observability. Every injected failure should emit something attributable: a log line with a chaos marker, ideally a metric. Otherwise the first person to see the error assumes it is real and the exercise becomes a support ticket.
Never enable in production, and enforce that in code. Environment-aware safeguards are only as good as your .env hygiene. Add a boot-time assertion that throws if chaos is enabled while app()->isProduction(), and keep the key out of your production secret store entirely. A chaos flag leaking into prod via a copied .env is an incident, not a test.
Config cache will eat your toggles. php artisan config:cache snapshots the file; flipping an env value afterwards does nothing and you will conclude the package is broken. Run php artisan config:clear after every toggle, or keep chaos disabled by design in cached environments.
Chaos multiplies your existing budgets. A job with three retries and a 60-second timeout turns a 5-minute queue drain into a 20-minute one — on shared staging that reads as an outage. Check retry counts and timeouts before turning probability up, and start at a few percent, not 50%.
Attribute every failure. Without a marker, injected errors are indistinguishable from real ones in the logs. A colleague debugging a staging spike needs one greppable identifier to know it was intentional.
Read the changelog with suspicion. 3.0.7 is maintenance only: Dependabot bumps to CI actions (actions/checkout 4→7, ramsey/composer-install 3→4, stefanzweifel/git-auto-commit-action 5→7, laravel-pint-action 2.3→2.6), Plumb/CI housekeeping, and new Pest tests. Those major numbers are CI tooling, not runtime breaks — do not misread them as breaking. Equally, do not assume future releases are as inert; diff tagged source on each bump.
Budget for support reality. Three stars, zero dependents, one maintainer, GitHub Issues as the only channel. Pin ^3.0, upgrade all Lara Zeus packages together in one PR, and add a contract test over the public surface you actually use so future minors stay covered. If a blocking bug lands, the escalation path is effectively "fork it" — confirm that is acceptable before this sits near anything critical.
Extension points worth knowing. The service provider's container bindings and the config-driven rule definitions are the first places to reach if you need custom failure types. Extend via your own wrapper and a custom rule rather than patching vendor code; the seam above is also where you swap the mechanism out entirely if the package goes quiet.
Sanity-check the release metadata. The latest tag is dated 2026-07-17 — future-dated relative to a normal review cycle. Verify against Packagist what you are actually installing and what the true latest stable is before pinning.
How can I help you explore Laravel packages today?