Packages@g14o/ratelimit-nextjs
Setup
Next.js App Router routes and per-user rate limiting.
Create a client
import { createRateLimit } from "@g14o/ratelimit-nextjs";
import { logger } from "@/lib/logger";
import { env } from "@/lib/env";
export const { withRateLimit, checkRateLimit, withUserRateLimit } =
createRateLimit({
redis: {
url: env.UPSTASH_REDIS_REST_URL,
token: env.UPSTASH_REDIS_REST_TOKEN,
},
logger,
});Store configuration (recommended)
import { createRateLimit } from "@g14o/ratelimit-nextjs";
import { upstashStore } from "@g14o/ratelimit-nextjs/upstash";
import { env } from "@/lib/env";
import { logger } from "@/lib/logger";
export const { withRateLimit } = createRateLimit({
store: upstashStore({
url: env.UPSTASH_REDIS_REST_URL,
token: env.UPSTASH_REDIS_REST_TOKEN,
}),
logger,
});Store helpers (memoryStore, upstashStore, createStore, defineStore) are exported from @g14o/ratelimit-nextjs and its /memory and /upstash subpaths. store and redis are mutually exclusive.
App Router route
Built-in tier limits are listed in @g14o/ratelimit setup — default tiers.
import { NextResponse } from "next/server";
import { withRateLimit } from "@/lib/rate-limit";
export const POST = withRateLimit(
async (req) => NextResponse.json({ ok: true }),
{ tier: "moderate" }
);Per-user limits
Use a verified identity from your auth provider (Better Auth, NextAuth, Clerk, etc.) — not client-controlled headers.
import { NextResponse } from "next/server";
import { withUserRateLimit } from "@/lib/rate-limit";
import { getSession } from "@/lib/auth";
export const POST = withUserRateLimit(
async (req) => NextResponse.json({ ok: true }),
async (req) => {
const session = await getSession(req);
return session?.user.id ?? null;
},
{ tier: "auth" }
);Middleware
Use checkRateLimit from your middleware when you need manual control:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { checkRateLimit } from "@/lib/rate-limit";
export async function POST(req: NextRequest) {
const result = await checkRateLimit(req, { tier: "strict" });
if (!result.ok) {
return NextResponse.json({ error: "Too many requests" }, { status: 429 });
}
}See @g14o/ratelimit middleware patterns for more examples (adapt Response to NextResponse).