Skip to content

@jfungus/ratelimit-hono

Rate limiting middleware for Hono - the fast, lightweight web framework for Edge runtimes.

Installation

Terminal window
npm install @jfungus/ratelimit-hono

Basic Usage

import { Hono } from "hono";
import { rateLimiter } from "@jfungus/ratelimit-hono";
const app = new Hono();
app.use(
rateLimiter({
limit: 100,
windowMs: 60 * 1000, // 1 minute
}),
);
app.get("/", (c) => c.text("Hello!"));
export default app;

Options

OptionTypeDefaultDescription
limitnumber | (c) => number60Max requests per window
windowMsnumber60000Window duration in ms
algorithm'fixed-window' | 'sliding-window''sliding-window'Algorithm
storeRateLimitStoreMemoryStoreStorage backend
keyGenerator(c) => stringIP-basedClient identifier
skip(c) => boolean-Skip rate limiting
handler(c, info) => Response429 responseCustom handler
dryRunbooleanfalseLog but don’t block

Dynamic Limits

Different limits for different users:

app.use(
rateLimiter({
limit: (c) => {
const isPremium = c.req.header("X-Premium");
return isPremium ? 1000 : 100;
},
windowMs: 60 * 1000, // 1 minute
}),
);

Per-Route Limits

const strictLimiter = rateLimiter({ limit: 10, windowMs: 60 * 1000 }); // 1 minute
const normalLimiter = rateLimiter({ limit: 100, windowMs: 60 * 1000 }); // 1 minute
app.use("/api/auth/*", strictLimiter);
app.use("/api/*", normalLimiter);

Access Rate Limit Info

app.get("/api/data", (c) => {
const info = c.get("rateLimit");
// { limit: 100, remaining: 99, reset: 1234567890 }
return c.json({ data: "hello", remaining: info.remaining });
});

Cloudflare Workers

For native Cloudflare rate limiting:

import { cloudflareRateLimiter } from "@jfungus/ratelimit-hono";
app.use(
cloudflareRateLimiter({
binding: env.RATE_LIMITER,
keyGenerator: (c) => c.req.header("CF-Connecting-IP") ?? "unknown",
}),
);

With Redis

import { createStorage } from "unstorage";
import redisDriver from "unstorage/drivers/redis";
import { createUnstorageStore } from "@jfungus/ratelimit-unstorage";
const store = createUnstorageStore({
storage: createStorage({
driver: redisDriver({ url: process.env.REDIS_URL }),
}),
});
app.use(rateLimiter({ limit: 100, windowMs: 60 * 1000, store })); // 1 minute