hono-rate-limiter
Rate limiting middleware for Hono with pluggable memory, Redis, Cloudflare, and Unstorage backends, plus WebSocket support.
Repository Health
Technical Analysis
hono-rate-limiter is a rate-limiting middleware built specifically for the Hono web framework, giving Hono apps a drop-in way to cap how many requests a client can make in a given time window. It ships a MemoryStore for single-instance deployments out of the box, and pluggable RedisStore, UnstorageStore, and Cloudflare Rate Limiting binding integrations for distributed or edge environments where in-process memory isn’t shared across instances.
Beyond plain HTTP middleware, the library also exports a webSocketLimiter that throttles inbound WebSocket messages using the same store abstraction, decrementing hit counts correctly based on whether the message handler succeeded or threw. It implements both the draft-6 and draft-7 IETF RateLimit-* header specifications, sets Retry-After on rejection, and lets callers configure custom key generation, skip logic, and success/failure classification to fit their own auth and observability setup.
What You Get
- A
rateLimiter()middleware factory that plugs directly into any Hono app’s middleware chain - Four store backends out of the box:
MemoryStore(default),RedisStore(Lua-script atomic increments),UnstorageStore(any unstorage-compatible driver), and a Cloudflare Rate Limiting binding path - A
webSocketLimiter()wrapper that rate-limits inbound WebSocket messages using the same store interface - Standardized
RateLimit-*response headers for both the draft-6 and draft-7 IETF rate-limit-headers specs, plusRetry-Afteron rejection - Configurable
keyGenerator,skip,requestWasSuccessful, and customhandlercallbacks for full control over identification, exemptions, and rejection responses
Common Use Cases
- Throttling public REST API endpoints built on Hono to a fixed number of requests per IP or API key within a time window
- Protecting authentication routes (login, signup, password reset) from brute-force and credential-stuffing attempts
- Sharing rate-limit state across multiple server instances or serverless invocations via the Redis or Unstorage store
- Applying Cloudflare’s native Rate Limiting binding when deploying a Hono app to Cloudflare Workers
- Capping the rate of inbound messages on a Hono WebSocket connection to prevent a single client from flooding the server
Under The Hood
Architecture
The library is organized around a small Store interface (increment, decrement, get, resetKey, optional init/resetAll/shutdown) that every backend implements, and two middleware entry points — rateLimiter() in src/rateLimiter.ts and webSocketLimiter() in src/websocket.ts — that share the same increment/decrement/header-setting flow against whichever store is injected. rateLimiter() itself dispatches on whether a binding (Cloudflare Rate Limiting) is present, routing to either the generic honoRateLimiter path (store-backed, header-aware) or a thin cloudflareRateLimiter path that just forwards to the platform binding’s own limit() call. initStore() in src/utils.ts validates a store implements increment before wiring it up, keeping the core middleware decoupled from any specific storage technology — swapping MemoryStore for RedisStore or UnstorageStore requires no change to the middleware logic itself.
Tech Stack
Written in TypeScript against Hono’s own Env/Input/MiddlewareHandler generic types (hono and unstorage are peer dependencies, not bundled), so the library adds no runtime framework dependency beyond Hono itself. The RedisStore talks to any redis-like client via injected Lua scripts (src/stores/redis/scripts.ts) executed through evalsha/scriptLoad, giving atomic increment/decrement without needing a specific Redis SDK pinned as a dependency. Builds are produced with pkgroll, dual ESM/CJS output is declared via exports conditions in package.json, and formatting/linting runs through Biome rather than ESLint/Prettier.
Code Quality
The project has extensive test coverage relative to its size — seven Vitest spec files (middleware.spec.ts, store.spec.ts, headers.spec.ts, options.spec.ts, websockets.spec.ts, plus a dedicated redis/__tests__ suite for the store constructor and Lua-script behavior) totaling over 1,600 lines, run against a real @hono/node-server instance via supertest rather than pure mocks. Error handling is explicit: the Redis store attaches no-op .catch() handlers to script-load promises specifically to avoid unhandled-rejection crashes while still surfacing the original error to any caller that awaits them, and inline comments document non-obvious decisions like why onError in the WebSocket wrapper never decrements the hit counter. CI runs a dedicated test workflow plus CodeQL scanning, and Biome enforces lint/format rules on every commit via a Husky pre-commit hook.
What Makes It Unique Most rate-limiting middleware in the Node ecosystem targets Express; this library re-implements the same configurable model (windowed limits, pluggable stores, standard headers, skip/key-generator hooks) natively for Hono’s context-based middleware signature, while adding two things most equivalents lack out of the box: a Cloudflare Rate Limiting binding integration for edge/Workers deployments, and a WebSocket-specific limiter that rate-limits individual inbound messages on a persistent connection rather than just HTTP request/response cycles.
Used by 4 apps in this directory
Formizee
Forms Surveys
An open-source form backend and builder platform — design forms, collect submissions, and get analytics without hosting your own server, positioned as an alternative to Formspree and Typeform.
Midday
Invoicing Finance · Productivity
All-in-one AI-powered business operations platform for freelancers and solo entrepreneurs to manage invoicing, time tracking, banking, and financial intelligence.
OpenStatus
Monitoring · Devops
Open-source status pages and uptime monitoring with global synthetic checks, monitoring-as-code, and AI agent integration via MCP.
Rallly
Scheduling
Self-hostable group scheduling polls that eliminate back-and-forth emails and find the best meeting time for everyone.