Every ThrottleKit adapter is thin glue. Each one resolves aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/AmeyaBorkar/throttlekit/llms.txt
Use this file to discover all available pages before exploring further.
Limiter, derives a limit key from the incoming request, runs the shared enforcement core, and maps the result onto whatever response shape the framework expects — a RequestHandler, a CanActivate guard, a thrown Response, a gRPC callback. The options surface (key, cost, fail, emit, onLimited, onError, handler) is identical across all 13 adapters, so switching frameworks changes the import path, not the policy.
All adapters
| Name | Import subpath | Framework | Notes |
|---|---|---|---|
expressRateLimit | throttlekit/express | Express | RequestHandler middleware |
fastifyRateLimit | throttlekit/fastify | Fastify v5 | onRequest hook |
koaRateLimit | throttlekit/koa | Koa v3 | Middleware |
honoRateLimit | throttlekit/hono | Hono v4 | MiddlewareHandler |
nextRateLimit | throttlekit/next | Next.js | Returns {limited, headers|response} — no "next" import |
nestRateLimit | throttlekit/nest | NestJS | CanActivate guard; @RateLimit decorator pattern |
sveltekitRateLimit | throttlekit/sveltekit | SvelteKit | handle hook for hooks.server.ts |
remixRateLimit | throttlekit/remix | Remix / React Router | Guard — throws a Response on deny |
elysiaRateLimit | throttlekit/elysia | Elysia | onBeforeHandle hook |
withRateLimit | throttlekit/fetch | Web fetch | Cloudflare Workers · Deno · Bun · Next.js edge |
trpcRateLimit | throttlekit/trpc | tRPC | t.middleware(...) |
grpcRateLimit | throttlekit/grpc | gRPC (grpc-js) | Built on createEnforcer; RESOURCE_EXHAUSTED on deny |
lambdaRateLimit | throttlekit/lambda | AWS Lambda | API Gateway v1 + v2; built on createEnforcer |
Shared options
All HTTP adapters acceptCommonAdapterOptions. The most commonly used fields are:
The algorithm that produces decisions —
gcra(...), fixedWindow(...), tokenBucket(...), etc. Alternatively pass a prebuilt { limiter }.Derive the limit key from a request. Defaults to a proxy-correct client IP. Override with an API token, user ID, or any string that identifies the requester.
Units to deduct per request. Default
1. Pass a function to charge writes more than reads, or to meter by payload size.What to do when the backing store is unreachable.
"open" admits the request (availability-first, the default). "closed" rejects with 503 (safety-first — use for auth, payments, or sign-up flows).Which header families to write. Default
{ draft: true }. Accepts { draft, structured, legacy } — see Standards headers below.Name surfaced inside structured-field headers. Defaults to the strategy name (e.g.
"gcra").Number of trusted reverse-proxy hops when reading
X-Forwarded-For. 0 (default) trusts no proxies; set to 1 behind a single load balancer.Aggregate IPv6 addresses to this prefix length (e.g.
64 buckets a /64 subnet together). Prevents trivial key rotation by cycling addresses.Observability hook fired on every denial, before the response is written. Use it to emit metrics or structured logs.
Observability hook fired when the backing store throws, before the
fail policy is applied.Custom
429 responder. When provided, it fully owns the denial response — the adapter will not write its default 429 body.Standards headers
buildRateLimitHeaders()
buildRateLimitHeaders accepts a Decision and an optional options object and returns a Record<string, string> ready to set on any response. ThrottleKit supports three header families, controlled by the emit option:
| Family | Headers emitted | Reset value |
|---|---|---|
draft (default) | RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset | Delta-seconds until replenishment |
structured | RateLimit, RateLimit-Policy (RFC 9651 Structured Fields, draft-11) | Delta-seconds |
legacy | X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset | Absolute epoch-seconds |
decision.allowed === false) a Retry-After header (delta-seconds, rounded up, minimum 1) is always added regardless of the emit selection.
createEnforcer() — custom and non-HTTP transports
For protocols that are not HTTP — message queues, job runners, WebSocket frames, gRPC, or any custom transport — use createEnforcer instead of an HTTP adapter. It exposes the same enforcement logic but returns a transport-neutral EnforceResult rather than writing a response.
Enforcer interface
EnforceResult fields
Whether to admit the request.
true for outcome "ok", and also for "error" under a fail-open policy; false for "limited" and for "error" under fail-closed.Which branch produced this result. Use this to distinguish a
429 ("limited") from a 503 ("error").The rate-limit decision, or
undefined when the store threw (outcome === "error").Standards-compliant response headers. Empty on
"error" or when emit is false.Milliseconds until the limit resets.
0 unless outcome is "limited".EnforceOptions
The rate-limiting strategy (or a prebuilt
{ limiter }).Store-outage behavior. Default
"open".Header families to include in
result.headers. Default { draft: true }. Pass false to suppress all headers.Name for structured-field headers.
Fired on every denial.
Fired when the store throws, before the fail policy is applied.
Security helpers
clientIp() / edgeClientIp()
Node adapters call nodeClientIp(req, trust) (reads socket peer + X-Forwarded-For through the configured trust chain). Edge adapters call edgeClientIp(request, trust, trustClientIpHeader) which trusts the platform header (cf-connecting-ip) first and only falls back to X-Forwarded-For when trustProxy is configured — returning "anon" rather than a spoofable key when no trusted source is present. Key derivation is a security control: a spoofable key lets a client bypass the limit by rotating addresses.
hashKey()
Pass any key through a one-way hash before storing it in the rate-limit store. Avoids holding raw IP addresses or user IDs (PII) in Redis.
hmacKeyer()
Build a keyed HMAC function once and use it as the key option. The secret prevents offline dictionary attacks against the store.
Next steps
- Node frameworks (Express, Fastify, Koa, Hono, Next.js, NestJS, tRPC, gRPC) → Node Frameworks
- Edge & serverless (Web fetch, SvelteKit, Remix, Elysia, AWS Lambda) → Edge & Serverless