Securityv0.1.4
@tekir/limiter
Rate limiting with memory and Redis stores.
Installation
$
bun add @tekir/limiterFeatures
- Memory, Redis, and database stores
- Per-route rate limiting middleware
- Configurable max requests and time window
- Identify by IP, user, or custom function
- Automatic X-RateLimit-* response headers
Quick Example
TypeScript
import { limiter } from '@tekir/limiter'
app.router.post('/login', [
limiter({ max: 5, window: 60, by: 'ip' }),
], loginHandler)Changelog
v0.1.4LatestSeptember 16, 2026
- Database-backed limits expire correctly and request identity no longer collapses unrelated client IPs into one quota.
- Published output now uses the shared Node-targeted ESM bundle pipeline with external dependencies and generated TypeScript declarations, while Bun consumers keep the native source export.
v0.1.3July 23, 2026
- Package metadata now follows the shared compatible
0.1.xdependency range used by this coordinated Tekir release.
v0.1.2July 16, 2026
- Redis rate limiting uses an atomic Lua consume operation for increment, TTL, and lockout decisions; memory-store cleanup and observation paths are bounded and consistent.
v0.1.1June 13, 2026
- The rate limiter no longer trusts
X-Forwarded-ForwithouttrustProxy. The newtrustProxyoption defaults tofalse, in which case onlyctx.request.ipis used; set it totrue(left-most) or a number of hops to parse the forwarded chain, so a client can no longer spoof its identity to dodge limits. - Counting is now atomic at the store level. The check-then-consume race is gone (a single atomic consume handles increment plus lockout), verified under concurrency, so a burst of simultaneous requests can never exceed the limit.
- Identifiers are URL-encoded before building the bucket key, so a
:in an IPv6 or custom identifier cannot collide with another bucket. The memory store now sweeps expired entries on a periodic, unref'd timer. Retry-Afteris now sent only when the limit is actually exceeded.- Found and fixed with Fable.
v0.1.0April 1, 2026
- Initial release