Packages@g14o/ratelimit-express
Setup
Express middleware, route wrappers, and per-user rate limiting.
Create a client
import { createRateLimit } from "@g14o/ratelimit-express";
export const {
middleware,
withRateLimit,
withUserRateLimit,
userMiddleware,
checkRateLimit,
} = createRateLimit({
redis: {
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
},
});Store configuration (recommended)
import { createRateLimit } from "@g14o/ratelimit-express";
import { upstashStore } from "@g14o/ratelimit-express/upstash";
export const { middleware, withRateLimit } = createRateLimit({
store: upstashStore({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
}),
});Store helpers (memoryStore, upstashStore, createStore, defineStore) are exported from @g14o/ratelimit-express and its /memory and /upstash subpaths. store and redis are mutually exclusive.
Route middleware (idiomatic Express)
Built-in tier limits are listed in @g14o/ratelimit setup — default tiers.
import express from "express";
import { middleware } from "../lib/ratelimit";
const router = express.Router();
router.get(
"/api/status",
middleware({ tier: "lenient" }),
(_req, res) => res.json({ ok: true })
);Wrapped route handler
import express from "express";
import { withRateLimit } from "../lib/ratelimit";
const router = express.Router();
router.post(
"/api/chat",
withRateLimit((_req, res) => res.json({ ok: true }), {
tier: "moderate",
prefix: "@ratelimit:chat",
})
);Per-user limits
Use a verified identity from upstream auth middleware (session, JWT, Passport, etc.) — not client-controlled headers.
import express from "express";
import { userMiddleware } from "../lib/ratelimit";
const router = express.Router();
router.post(
"/api/user-action",
userMiddleware(async (req) => req.user?.id ?? null, { tier: "auth" }),
(_req, res) => res.json({ ok: true })
);Manual check
Use checkRateLimit when you need full control over the response:
import type { Request, Response } from "express";
import { checkRateLimit } from "../lib/ratelimit";
export async function customHandler(req: Request, res: Response) {
const result = await checkRateLimit(req, { tier: "strict" });
if (!result.ok) {
return res.status(429).json({ error: "Too many requests" });
}
res.json({ ok: true });
}