Packages@g14o/ratelimit
Route handlers & middleware
withRateLimit, checkRateLimit, per-user limits, and custom identifiers.
App Router route
Pass a tier to select a built-in limit profile. See default tiers for built-in limits.
import { withRateLimit } from "@/lib/ratelimit";
export const POST = withRateLimit(
async (req) => Response.json({ ok: true }),
{ tier: "moderate" }
);Manual check (middleware or custom flow)
Use checkRateLimit when you are not wrapping a route handler:
import { checkRateLimit } from "@/lib/ratelimit";
export async function POST(req: Request) {
const result = await checkRateLimit(req, { tier: "strict" });
if (!result.ok) {
return Response.json({ error: "Too many requests" }, { status: 429 });
}
// ...
}Per-user rate limit
Use a verified identity from your auth provider — not client-controlled headers.
import { withUserRateLimit } from "@/lib/ratelimit";
import { getSession } from "@/lib/auth";
export const POST = withUserRateLimit(
async (req) => Response.json({ ok: true }),
async (req) => {
const session = await getSession(req);
return session?.user.id ?? null;
},
{ tier: "auth" }
);Custom identifier
import { withRateLimit } from "@/lib/ratelimit";
export const GET = withRateLimit(
async (req) => Response.json({ ok: true }),
{
tier: "lenient",
identifierFn: async (req) =>
req.headers.get("x-api-key") ?? "anonymous",
}
);