Hono Rate Limiter Middleware
hono-rate-limiter is a middleware library designed for the Hono web framework, providing robust rate-limiting capabilities for both HTTP API endpoints and WebSocket connections. Its current stable version is 0.5.3, with minor releases occurring relatively frequently, indicating active development. The library is inspired by the widely-used `express-rate-limit` and aims to bring similar comprehensive functionality to Hono applications, focusing on developer experience and flexibility. A key differentiator is its flexible storage mechanism, now supporting Unstorage, which allows developers to integrate various backends like Redis, Cloudflare KV, or file systems for persistent rate limit tracking. It simplifies the process of protecting Hono routes from abuse and ensures API stability under high traffic, offering fine-grained control over rate limits and responses.
Common errors
-
TypeError: keyGenerator is not a function or is missing
cause The `keyGenerator` option was omitted from the `rateLimiter` configuration after it became a required parameter in `v0.3.0`.fixAdd `keyGenerator: (c) => c.req.ip` or a custom function to your `rateLimiter` options. -
Error: Invalid store. Please provide a valid store implementation.
cause The `store` option for `rateLimiter` was either not provided or an invalid object was passed, preventing the middleware from initializing properly.fixEnsure you are passing a valid store instance, e.g., `store: new MemoryStore()` or `store: new RedisStore(...)` after installing the appropriate package. -
TypeError: rateLimiter is not a function
cause Attempting to use `require()` for importing `hono-rate-limiter` in an ESM context, or incorrectly trying to import it as a default export.fixUse ESM named imports: `import { rateLimiter } from 'hono-rate-limiter';`.
Warnings
- breaking As of `v0.5.0`, specialized Cloudflare KV and Durable Object stores were removed from the main `hono-rate-limiter` package. If you were using these, you now need to explicitly use the `@hono-rate-limiter/cloudflare` package.
- breaking In `core-0.3.0`, the `keyGenerator` option became a required parameter for the `rateLimiter` configuration. Omitting it will lead to runtime errors.
- breaking Support for built-in Redis stores was dropped in `core-0.2.0`. Users who relied on this feature must now use a separate data store package, such as `@hono-rate-limiter/redis` or an `unstorage` compatible store.
- gotcha The package is still actively in development. While functional, it might undergo further API changes or feature adjustments in future minor versions. Feedback is highly appreciated by the maintainers.
Install
-
npm install hono-rate-limiter -
yarn add hono-rate-limiter -
pnpm add hono-rate-limiter
Imports
- rateLimiter
const rateLimiter = require('hono-rate-limiter');import { rateLimiter } from 'hono-rate-limiter'; - WebSocketLimiter
import WebSocketLimiter from 'hono-rate-limiter';
import { WebSocketLimiter } from 'hono-rate-limiter'; - MemoryStore
import { MemoryStore } from 'hono-rate-limiter';import { MemoryStore } from 'hono-rate-limiter/stores'; - Store
import { Store } from 'hono-rate-limiter';import type { Store } from 'hono-rate-limiter';
Quickstart
import { Hono } from 'hono';
import { rateLimiter } from 'hono-rate-limiter';
import { MemoryStore } from 'hono-rate-limiter/stores';
const app = new Hono();
// Configure the rate limiter middleware
const limiter = rateLimiter({
windowMs: 60 * 1000, // 1 minute
limit: 5, // Limit each IP to 5 requests per minute
standardHeaders: 'draft-7', // Set standard rate limit headers
legacyHeaders: false, // Disable X-RateLimit-* headers
// keyGenerator: (c) => c.req.ip, // Uses client IP by default if not provided
store: new MemoryStore(), // In-memory store (not recommended for production)
message: 'You are making too many requests. Please try again soon.',
handler: (c) => {
return c.json({
status: 429,
message: 'Too many requests, please try again after some time.'
}, 429)
}
});
// Apply the rate limiter globally or to specific routes
app.use(limiter);
app.get('/', (c) => {
return c.text('Welcome to the Hono Rate Limited API!');
});
app.get('/protected', (c) => {
return c.json({ data: 'This is protected data.' });
});
export default app;