npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@priyabrat/chaos-route

v0.0.4

Published

Test your application by injecting intentional error to your route

Readme

Chaos Route

npm version

Intentionally break your Express.js API routes to test how your application handles failures.

Chaos Route is an Express middleware package for controlled fault injection during development and testing.

It lets you configure failures for specific routes without modifying your controllers or frontend code.

For example, you can make /api/login timeout, return a 500 error, or introduce artificial latency simply by changing chaos.config.json.


Table of Contents


Why Chaos Route?

Applications usually work perfectly during development.

But what happens when:

  • Login takes too long?
  • An API suddenly returns 500?
  • A request is delayed by several seconds?
  • Your frontend receives an unexpected backend failure?
  • Your loading state never finishes?
  • Your error handling isn't actually working?

Chaos Route lets you intentionally create these situations so you can test how your application behaves when things go wrong.


Installation

npm install @priyabrat/chaos-route;

OR

npm install @priyabrat/chaos-route -D;

Quick Start

1. Add Chaos Route to your Express application

import express from "express";
import { chaos } from "@priyabrat/chaos-route";

const app = express();

app.use(chaos());

app.post("/api/login", loginController);

app.listen(5000, () => {
    console.log("Server running on port 5000");
});

Place chaos() before the routes you want to test.


2. Create chaos.config.json

Create this file in the root of your application:

my-express-app/
├── src/
├── package.json
├── chaos.config.json
└── ...

Example:

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "http_error",
        "status": 500,
        "message": "Login service failed"
      }
    }
  }
}

Now every request to:

POST /api/login

will receive the configured failure instead of reaching your login controller.


How It Works

Chaos Route runs as normal Express middleware.

Client
  │
  │ POST /api/login
  ▼
Express
  │
  ▼
Chaos Route
  │
  ├── No configuration ──────→ next()
  │
  ├── Latency ────────────────→ wait → next()
  │
  └── HTTP Error ─────────────→ return error

Your existing controllers don't need to know that Chaos Route is being used.

For example:

app.use(chaos());

app.post("/api/login", loginController);

With no failure configured:

Request
   ↓
Chaos Route
   ↓
loginController
   ↓
Response

With an HTTP error configured:

Request
   ↓
Chaos Route
   ↓
500 Error

The loginController is never executed.


Configuration

The configuration file(chaos.config.json) uses this structure:

{
  "routes": {
    "/your-route": {
      "failure": {
        "type": "...",
        "status": "code",
        "message": "..."
      }
    }
  }
}

Each route can have its own failure configuration.


HTTP Error

Return a controlled HTTP error from a route.

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "http_error",
        "status": 500,
        "message": "Login service unavailable"
      }
    }
  }
}

A request to /api/login will receive:

{
  "error": "Login service unavailable",
  "chaos": true
}

Options

| Option | Type | Default | Description | | --------- | -------------- | --------------- | ---------------- | | type | "http_error" | — | Failure type | | status | number | 500 | HTTP status code | | message | string | "Chaos Error" | Error message |

You can simulate different HTTP failures:

{
  "type": "http_error",
  "status": 401,
  "message": "Unauthorized"
}

or:

{
  "type": "http_error",
  "status": 503,
  "message": "Service unavailable"
}

Latency

Artificially delay a request before allowing it to continue to the real Express route.

{
  "routes": {
    "/api/users": {
      "failure": {
        "type": "latency",
        "latencyMs": 3000
      }
    }
  }
}

The request flow becomes:

Client
   ↓
/api/users
   ↓
Chaos Route
   ↓
⏳ 3 seconds
   ↓
usersController
   ↓
Response

Options

| Option | Type | Default | Description | | ----------- | ----------- | ------- | --------------------- | | type | "latency" | — | Failure type | | latencyMs | number | 3000 | Delay in milliseconds |


Timeout

Simulate a request that hangs for a specified duration and then terminates the connection.

{
  "routes": {
    "/api/users": {
      "failure": {
        "type": "timeout",
        "timeoutMs": 3000
      }
    }
  }
}

A request to /api/users will hang for 3 seconds and then the connection will be terminated.

Options

| Option | Type | Default | Description | | ----------- | ----------- | ------- | ---------------------------------------- | | type | "timeout" | — | Failure type | | timeoutMs | number | 5000 | Time before the connection is terminated |


Connection Error

Immediately terminate the connection to simulate a connection failure.

{
  "routes": {
    "/api/users": {
      "failure": {
        "type": "connection_error"
      }
    }
  }
}

A request to /api/users will have its connection terminated without receiving a response.

Options

| Option | Type | Default | Description | | ------ | -------------------- | ------- | ------------ | | type | "connection_error" | — | Failure type |


Rate Limit

Limit requests to an endpoint and return 429 when the limit is exceeded.

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "rate_limit",
        "limit": 5,
        "windowMs": 60000
      }
    }
  }
}

After 5 requests within 60 seconds, further requests will receive a 429 Too Many Requests response.

Options

| Option | Type | Default | Description | | ---------- | -------------- | ------- | --------------------------- | | type | "rate_limit" | — | Failure type | | limit | number | 10 | Maximum requests allowed | | windowMs | number | 60000 | Time window in milliseconds |


Request Manipulation

Modify, add, or remove request fields before they reach your controller.

{
  "routes": {
    "/api/profile": {
      "request": {
        "remove": ["email"],
        "set": {
          "age": 99
        },
        "add": {
          "chaosTest": true
        }
      }
    }
  }
}

Add Request Fields

Use add to add fields to the request.

"add": {
  "chaosTest": true
}

Modify Request Fields

Use set to modify existing request fields.

"set": {
  "age": 99
}

Remove Request Fields

Use remove to remove fields from the request.

"remove": ["email"]

The modified request is then passed to your existing controller.


Response Manipulation

Modify, add, or remove response fields before they reach the client.

{
  "routes": {
    "/api/profile": {
      "response": {
        "remove": ["email"],
        "set": {
          "age": 99
        },
        "add": {
          "chaosTest": true
        }
      }
    }
  }
}

Add Response Fields

Use add to add fields to the response.

"add": {
  "chaosTest": true
}

Modify Response Fields

Use set to modify existing response fields.

"set": {
  "age": 99
}

Remove Response Fields

Use remove to remove fields from the response.

"remove": ["email"]

The modified response is then sent to the client.


Multiple Routes

You can configure different failures for different endpoints.

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "http_error",
        "status": 500,
        "message": "Login service failed"
      }
    },

    "/api/users": {
      "failure": {
        "type": "latency",
        "latencyMs": 3000
      }
    }
  }
}

Now:

/api/login
    ↓
500 Error

/api/users
    ↓
3 second delay
    ↓
Normal controller

Routes Without Chaos

Routes that aren't configured are completely unaffected.

For example:

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "http_error",
        "status": 500
      }
    }
  }
}

A request to:

/api/products

will simply continue through Express normally.

/api/products
      ↓
Chaos Route
      ↓
next()
      ↓
productsController

Disabling a Failure

Remove the failure configuration from the route:

{
  "routes": {
    "/api/login": {}
  }
}

You can also remove the route completely:

{
  "routes": {}
}

OR

Add this inside your .env

CHAOS="false"

The request will pass through normally.

Configuration Reference

Current supported failure types:

| Failure | Description | | ------------ | ----------------------------------- | | http_error | Return a configured HTTP error | | latency | Delay the request before continuing | | connection_error | Destoy the connection | | timeout | hangs req for specific period then terminates connection | | rate_limit | Limit requests to an endpoint and return 429 when the limit is exceeded. |

Supported manipulation:

| type | Description | | ------------ | ----------------------------------- | | request | Modify, add, or remove request fields before they reach your controller. | | response | Modify, add, or remove request fields before they reach to client. |

More failure types are planned as Chaos Route evolves.


Example Express Application

import express from "express";
import { chaos } from "@priyabrat/chaos-route";

const app = express();

app.use(express.json());

app.use(chaos());

app.post("/api/login", (req, res) => {
  res.json({
    message: "Login successful"
  });
});

app.get("/api/users", (req, res) => {
  res.json([
    { id: 1, name: "John" },
    { id: 2, name: "Jane" }
  ]);
});

app.listen(5000, () => {
  console.log("Server running on port 5000");
});

With:

{
  "routes": {
    "/api/login": {
      "failure": {
        "type": "http_error",
        "status": 500,
        "message": "Something went wrong"
      }
    },

    "/api/users": {
      "failure": {
        "type": "latency",
        "latencyMs": 5000
      }
    }
  }
}

You can test how your application handles both failures without changing either controller.


Version History

Version - Current

Request/Response Manipulation

Add request/response fields Modify request/response fields Remove request/response fields

Version

Failure Injection

  • [x] Timeout
  • [x] Connection errors
  • [x] Rate limiting (429)

Version — Initial Release

  • [x] HTTP errors
  • [x] Latency injection

Important

Chaos Route is intended primarily for development and testing.

Avoid enabling failure configurations in production unless you explicitly understand the consequences.

A good practice is to use Chaos Route only in development/test environments.


Roadmap

Planned failure types and features include:

  • [x] Timeout
  • [x] Connection errors
  • [x] Rate limiting (429)
  • [ ] Custom responses
  • [x] Request/response manipulation
  • [x] Better configuration validation
  • [x] Environment-based configuration
  • [ ] More fault-injection strategies

Contributing

Contributions, ideas, bug reports, and feature requests are welcome.

If you find a bug or have an idea for a new failure type, open an issue or submit a pull request.


License

License: MIT


Built for developers who want to test what happens when their APIs don't behave perfectly.