{"id":18336,"library":"express-idempotency-middleware","title":"Express Idempotency Middleware","description":"Express middleware for idempotent POST requests using Idempotency-Key header (version 1.0.2, stable release, active development). Provides pluggable stores (Memory, Redis, Postgres), in-flight concurrency control with wait or reject strategies, and safe response replay with header whitelist. TypeScript-first, ESM-only, requires Node ≥18 and Express 4 or 5. Differentiators: built-in in-flight handling via wait timeout polling, stable response fingerprinting, and separate replay header whitelist for security-aware caching of location headers without cookies or auth tokens. Designed for payment, order, and webhook idempotency scenarios.","status":"active","version":"1.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/YevhenMykhailenko/idempotency-express","tags":["javascript","express","middleware","idempotency","idempotent","api","webhooks","payments","typescript"],"install":[{"cmd":"npm install express-idempotency-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add express-idempotency-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add express-idempotency-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency: middleware integrates with Express request/response objects","package":"express","optional":false}],"imports":[{"note":"ESM-only package; CommonJS require is not supported","wrong":"const { idempotencyMiddleware } = require('express-idempotency-middleware')","symbol":"idempotencyMiddleware","correct":"import { idempotencyMiddleware } from 'express-idempotency-middleware'"},{"note":"MemoryStore is a named export, not a default export or subpath","wrong":"import MemoryStore from 'express-idempotency-middleware/MemoryStore'","symbol":"MemoryStore","correct":"import { MemoryStore } from 'express-idempotency-middleware'"},{"note":"Type-only import for TypeScript; requires 'type' keyword for runtime efficiency","wrong":"import { IdemOptions } from 'express-idempotency-middleware'","symbol":"IdemOptions","correct":"import type { IdemOptions } from 'express-idempotency-middleware'"}],"quickstart":{"code":"import express from 'express';\nimport { idempotencyMiddleware, MemoryStore } from 'express-idempotency-middleware';\n\nconst app = express();\napp.use(express.json());\n\nconst store = new MemoryStore();\n\napp.post(\n  '/payments',\n  idempotencyMiddleware({\n    store,\n    ttlMs: 24 * 60 * 60 * 1000,\n    inFlight: { strategy: 'wait', waitTimeoutMs: 3000, pollMs: 100 },\n    replay: { headerWhitelist: ['location'] }\n  }),\n  async (req, res) => {\n    const orderId = 'ord_' + Math.random().toString(36).slice(2);\n    res.setHeader('Location', `/orders/${orderId}`);\n    res.status(201).json({ orderId });\n  }\n);\n\napp.listen(3000);","lang":"typescript","description":"Creates an Express app with idempotency middleware on POST /payments, using MemoryStore, wait strategy for in-flight requests, and replay header whitelist."},"warnings":[{"fix":"Use ESM imports: import { idempotencyMiddleware } from 'express-idempotency-middleware'","message":"ESM-only package: require() throws ERR_REQUIRE_ESM","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Implement custom store implementing Store interface or use provided examples for RedisStore/PostgresStore","message":"MemoryStore does not persist across server restarts; use Redis or Postgres store in production","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always send a valid non-empty Idempotency-Key header, or set requireKey:true to enforce","message":"Idempotency-Key is case-sensitive and must be a string; omit or empty key with requireKey:false returns 400","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade Node.js to version 18 or later","message":"Node.js <18 is not supported; engines field specifies >=18.0.0","severity":"deprecated","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Change to ESM import: import { idempotencyMiddleware } from 'express-idempotency-middleware' or use dynamic import()","cause":"Using CommonJS require() instead of ESM import","error":"SyntaxError: Named export 'idempotencyMiddleware' not found. The requested module 'express-idempotency-middleware' is a CommonJS module which may not support all module.exports as named exports."},{"fix":"Ensure custom store implements Store interface with get(key), set(key, value, ttl?), and delete(key) async methods","cause":"Custom store does not implement required store interface (get, set, delete methods)","error":"TypeError: store.get is not a function"},{"fix":"Ensure all retries use exactly the same request body, headers (except whitelist), and method","cause":"Idempotency-Key reused with different request body or method than original","error":"Idempotency-Status: conflict (409)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}