{"id":17460,"library":"parrot-middleware","title":"Parrot Middleware for Express","description":"parrot-middleware is an Express.js middleware designed for mocking HTTP requests in development and testing environments. It allows developers to define a collection of 'scenarios', each comprising a list of request-response pairs. Based on the active scenario, the middleware intercepts matching incoming requests and serves the predefined mock responses. It provides dedicated control routes (`/parrot/scenario` for setting/getting the active scenario, and `/parrot/scenarios` for inspecting all available scenarios) to manage its behavior dynamically. Currently at stable version 5.3.0, the package sees active maintenance with frequent patch and minor releases, ensuring compatibility and addressing issues. Its key differentiator is the scenario-driven approach, making it easy to simulate complex backend states or error conditions without modifying frontend code or spinning up a full backend.","status":"active","version":"5.3.0","language":"javascript","source_language":"en","source_url":"https://github.com/americanexpress/parrot","tags":["javascript"],"install":[{"cmd":"npm install parrot-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add parrot-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add parrot-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This package is an Express.js middleware and requires Express to function.","package":"express","optional":false}],"imports":[{"note":"Modern Node.js projects primarily use ESM `import` syntax. While CommonJS `require` is still supported, `import` is the recommended and cleaner approach when `type: module` is set in `package.json`.","wrong":"const parrot = require('parrot-middleware');","symbol":"parrot","correct":"import parrot from 'parrot-middleware';"},{"note":"Scenarios are typically defined in a separate file (e.g., `scenarios.js`) and default-exported. Ensure the file extension (`.js`) is included when using ESM imports in Node.js, unless a bundler handles it.","wrong":"const scenarios = require('./scenarios.js');","symbol":"scenarios","correct":"import scenarios from './scenarios.js';"},{"note":"While not directly imported for runtime, type definitions for configuration options are available for TypeScript users.","symbol":"ParrotMiddlewareOptions","correct":"import { ParrotMiddlewareOptions } from 'parrot-middleware';"}],"quickstart":{"code":"import express from 'express';\nimport parrot from 'parrot-middleware';\n\n// scenarios.js\nconst scenarios = {\n  'has one ship': [\n    {\n      request: '/ship_log',\n      response: {\n        body: [{ name: 'The Jolly Roger', captain: 'Captain Hook' }],\n      },\n    },\n  ],\n  'has more ships': [\n    {\n      request: '/ship_log',\n      response: {\n        body: [\n          { name: 'The Jolly Roger', captain: 'Captain Hook' },\n          { name: 'The Black Pearl', captain: 'Jack Sparrow' },\n        ],\n      },\n    },\n  ],\n};\n\nconst app = express();\n\napp.use(express.json()); // Required for parsing JSON bodies for scenario POST requests\napp.use(parrot(scenarios));\n\napp.get('/', (req, res) => res.send('Hello from main app!'));\n\napp.listen(3001, () => {\n  console.log('Server running on http://localhost:3001');\n  console.log('Try: POST http://localhost:3001/parrot/scenario with { \"scenario\": \"has one ship\" }');\n  console.log('Then: GET http://localhost:3001/ship_log');\n});\n","lang":"javascript","description":"This example sets up an Express server with `parrot-middleware`, defining two basic scenarios. It demonstrates how to initialize the middleware with scenario definitions and provides instructions on how to activate a scenario via a POST request and then fetch the mocked data."},"warnings":[{"fix":"Consult the main Parrot repository's changelog or migration guides for core breaking changes. Thoroughly test existing mock configurations after upgrading.","message":"Version 5.0.0 was a major release, but the changelog provided does not detail specific breaking changes for `parrot-middleware`. Users upgrading from v4.x should review the `parrot` core package changes or test thoroughly for potential API alterations in middleware options or scenario processing, particularly regarding configuration structures or default behaviors.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Ensure `app.use(parrot(scenarios));` is placed early in your Express application's middleware chain, typically before most `app.get()`, `app.post()` etc., route definitions.","message":"The `parrot-middleware` must be placed before any other routes it is intended to intercept. If another route handler matches a path before `parrot` processes it, the mock will not be served.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Add `app.use(express.json());` (or `app.use(bodyParser.json());` for older Express versions) before `app.use(parrot(scenarios));` in your server setup.","message":"To allow the `/parrot/scenario` POST endpoint to receive and parse JSON payloads for setting the active scenario, `express.json()` middleware (or an alternative body parser) must be enabled *before* `parrot-middleware`.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"For POST, PUT, DELETE, etc., mocks, explicitly add `{ request: { path: '/your_path', method: 'POST' }, response: ... }` to your scenario definitions.","message":"When defining scenarios, ensure that your `request` objects specify the `method` if you intend to mock non-GET requests. By default, requests are matched with `GET` if no method is specified in the scenario.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Review your middleware chain and scenario response logic. Ensure that once a mock response is served, no subsequent middleware attempts to send another response. Also, verify `next()` is called correctly if `parrot-middleware` doesn't handle a request.","cause":"This typically occurs in Express when a response is attempted to be sent multiple times, often due to improper `next()` calls or asynchronous operations resolving after a response has already been sent.","error":"Error: Can't set headers after they are sent to the client."},{"fix":"If using Node.js modules (ESM), use `import parrot from 'parrot-middleware';`. If strictly CommonJS, ensure your `package.json` does not have `\"type\": \"module\"` and use `const parrot = require('parrot-middleware');`.","cause":"This error usually indicates that the `parrot` export was not correctly imported, most commonly by attempting a CommonJS `require` call on an ESM default export or vice versa, or a named import instead of a default.","error":"TypeError: parrot is not a function"},{"fix":"Double-check the scenario name for typos, case sensitivity, and ensure it corresponds precisely to a key in your `scenarios.js` (or equivalent) definition.","cause":"The scenario name provided in the POST request to `/parrot/scenario` does not exactly match any of the keys in your `scenarios` object.","error":"No scenario named '...' found"}],"ecosystem":"npm","meta_description":null}