
Engineering Overview
idempotency-kit packages two primitives every write API eventually needs. `withIdempotency` runs an operation at most once per key — the Stripe Idempotency-Key pattern — so client double-clicks, network retries, and webhook redeliveries don't charge, send, or create twice. A fingerprint guard rejects an idempotency key that's reused for a different request body, catching a class of client bugs. `RateLimiter` is a sliding-window limiter (smoother than fixed windows — no boundary bursts). Both run on a tiny pluggable async Store: an in-memory store ships in the box, and the one operation that must be atomic lives in the store (a SETNX / Lua script in Redis) rather than smeared across application code, so swapping to a distributed store changes nothing above it. Zero runtime dependencies, fully typed ESM, and deterministic — the clock is injectable, so tests need no real time or network.
The Problem
Networks retry, clients double-click, and webhooks redeliver — so any write endpoint that isn't explicitly idempotent will eventually charge, send, or create something twice. Teams re-solve this badly in app code (non-atomic check-then-write races) and reach for a fixed-window rate limiter that lets bursts through at the window boundary.
The Solution
Two small, correct primitives behind a pluggable store: an at-most-once idempotency wrapper with a fingerprint guard, and a sliding-window rate limiter. The single operation that must be atomic is isolated in the store (SETNX/Lua in Redis), so the rest is plain, testable code and the same API works in-memory or distributed.
Key Engineering Challenges
The key correctness decision was confining atomicity to the store boundary: the check-then-write that must not race is a single store operation (a SETNX or Lua script in Redis), so application code can't accidentally introduce a window between the check and the write. Making the clock injectable was the other deliberate choice — sliding-window expiry and idempotency TTLs are time-dependent, and a real clock makes those tests flaky, so the whole kit is deterministic and runs offline in CI.
Core Capabilities
System Architecture
System Architecture
Idempotency
Rate limiting
Store
"Application code calls the two primitives; correctness-critical atomicity is delegated to the store. The in-memory store makes everything testable offline; a Redis store makes it distributed with no changes above the store boundary."