rate-flex
v1.0.1
Published
Flexible rate limiting for Node.js - works with Express, Fastify, Koa, NestJS, and any framework
Maintainers
Readme
Rate Flex
Flexible rate limiting for Node.js - works with Express, Fastify, Koa, NestJS, and any framework.
Features
- Universal: Works with any Node.js framework
- Advanced Algorithms: Sliding window and token bucket
- Built-in Protection: Auth, OTP, brute force, and scraping prevention
- Scalable: In-memory or Redis storage
- Production Ready: Comprehensive error handling and monitoring
Installation
npm install rate-flexQuick Start
Express
import express from 'express';
import { expressRateLimit } from 'rate-flex';
const app = express();
app.use(expressRateLimit({
window: '1m',
max: 100,
strategy: 'sliding',
identifier: ['ip']
}));Fastify
import Fastify from 'fastify';
import { fastifyRateLimit } from 'rate-flex';
const fastify = Fastify();
fastify.register(fastifyRateLimit({
window: '1m',
max: 60,
strategy: 'sliding',
identifier: ['ip']
}));Koa
import Koa from 'koa';
import { koaRateLimit } from 'rate-flex';
const app = new Koa();
app.use(koaRateLimit({
window: '1m',
max: 50,
strategy: 'sliding',
identifier: ['ip']
}));NestJS
import { Module, Controller, Post } from '@nestjs/common';
import { SecurityModule, AuthRateLimit } from 'rate-flex';
@Module({
imports: [SecurityModule.forRoot({ store: 'memory' })],
})
export class AppModule {}
@Controller('auth')
export class AuthController {
@AuthRateLimit()
@Post('login')
async login() {
// Protected endpoint
}
}Vanilla Node.js
import { UniversalRateLimiter } from 'rate-flex';
const limiter = new UniversalRateLimiter({ store: 'memory' });
const result = await limiter.checkLimit(req, {
window: '1m',
max: 30,
strategy: 'sliding',
identifier: ['ip']
});
if (!result.allowed) {
// Handle rate limit exceeded
}Configuration
Basic Options
{
window: '1m', // Time window: '1s', '1m', '1h', '1d'
max: 100, // Max requests in window
strategy: 'sliding', // 'sliding' | 'token-bucket'
identifier: ['ip'], // ['ip', 'userId', 'apiKey', 'userAgent']
// Advanced options
slowDownAfter: 80, // Start slowing after N requests
delayMs: 1000, // Slowdown delay
blockAfter: 5, // Block after N violations
blockDuration: '15m', // Block duration
}Storage Configuration
// In-memory (single server)
const limiter = new UniversalRateLimiter({
store: 'memory'
});
// Redis (distributed)
const limiter = new UniversalRateLimiter({
store: 'redis',
redis: {
host: 'localhost',
port: 6379,
password: 'your-password'
}
});Built-in Protection
Authentication
import { expressAuth } from 'node-rate-limiter-universal';
app.use('/auth', expressAuth({
max: 5, // 5 attempts per 15 minutes
blockDuration: '30m' // Block for 30 minutes
}));API Protection
import { expressApi } from 'node-rate-limiter-universal';
app.use('/api', expressApi({
max: 1000, // 1000 requests per hour
slowDownAfter: 800 // Slow down at 80% capacity
}));Strict Protection
import { expressStrict } from 'node-rate-limiter-universal';
app.use('/admin', expressStrict({
max: 10, // Only 10 requests per minute
blockAfter: 3 // Block after 3 violations
}));Advanced Usage
Custom Rate Limiting
const limiter = new UniversalRateLimiter({
store: 'redis',
redis: { host: 'localhost', port: 6379 }
});
const result = await limiter.checkLimit({
ip: '192.168.1.1',
userId: 'user123',
endpoint: '/api/upload',
method: 'POST'
}, {
window: '1h',
max: 10,
strategy: 'sliding',
identifier: ['userId'],
blockAfter: 3,
blockDuration: '2h'
});Dynamic Management
// Whitelist/blacklist
await limiter.addToWhitelist('192.168.1.100');
await limiter.addToBlacklist('192.168.1.200', '24h');
// Reset limits
await limiter.resetLimit({
ip: '192.168.1.1',
userId: 'user123',
endpoint: '/api/data',
method: 'GET'
});Production Setup
Environment Configuration
const limiter = new UniversalRateLimiter({
store: process.env.NODE_ENV === 'production' ? 'redis' : 'memory',
redis: {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379'),
password: process.env.REDIS_PASSWORD
}
});Docker Compose
version: '3.8'
services:
app:
build: .
environment:
- REDIS_HOST=redis
- REDIS_PASSWORD=secure-password
depends_on:
- redis
redis:
image: redis:7-alpine
command: redis-server --requirepass secure-passwordAPI Reference
Rate Limit Options
| Option | Type | Description |
|--------|------|-------------|
| window | string | Time window ('1s', '1m', '1h', '1d') |
| max | number | Maximum requests in window |
| strategy | string | 'sliding' or 'token-bucket' |
| identifier | array | ['ip', 'userId', 'apiKey', 'userAgent'] |
| slowDownAfter | number | Start slowing after N requests |
| delayMs | number | Slowdown delay in milliseconds |
| blockAfter | number | Block after N violations |
| blockDuration | string | Block duration |
Framework Integrations
| Framework | Import | Usage |
|-----------|--------|-------|
| Express | expressRateLimit | app.use(expressRateLimit(options)) |
| Fastify | fastifyRateLimit | fastify.register(fastifyRateLimit(options)) |
| Koa | koaRateLimit | app.use(koaRateLimit(options)) |
| NestJS | @RateLimit | @RateLimit(options) decorator |
| Universal | UniversalRateLimiter | new UniversalRateLimiter(config) |
License
MIT
