Skip to content

iboruch/RateLimitSheesh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

portable-rate-limit

A dependency-free Node.js rate limiter you can add to almost any project. It includes:

  • a portable check() API for any Node.js source code
  • Express-style middleware
  • an in-memory token bucket store
  • a small store interface so you can add Redis, database, or shared cache storage later

Install

npm install portable-rate-limit

For local testing before publishing:

npm install ../path/to/portable-rate-limit

Use in any Node.js code

const { createRateLimiter } = require('portable-rate-limit');

const limiter = createRateLimiter({
  limit: 10,
  windowMs: 60_000
});

async function handleLogin(userId) {
  const result = await limiter.check({ key: `login:${userId}` });

  if (!result.allowed) {
    throw new Error(`Try again in ${Math.ceil(result.retryAfterMs / 1000)} seconds`);
  }

  return doLogin(userId);
}

Use with Express

const express = require('express');
const { expressRateLimit } = require('portable-rate-limit');

const app = express();

app.use(expressRateLimit({
  limit: 100,
  windowMs: 15 * 60 * 1000,
  keyGenerator: ({ req }) => req.ip
}));

app.get('/', (req, res) => {
  res.json({ ok: true });
});

When a request is blocked, the middleware returns HTTP 429 and sets:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset
  • Retry-After

Options

createRateLimiter({
  limit: 60,                    // max tokens in the bucket
  windowMs: 60_000,             // time to fully refill the bucket
  keyGenerator: ({ req, key }) => key || req.ip,
  skip: ({ req }) => false,
  onLimit: (input, result) => {},
  store: customStore
});

The default store is in memory. That is fine for one Node.js process. For multiple servers or serverless deployments, provide a shared store backed by Redis or a database.

Custom store interface

const store = {
  async get(key) {
    return bucket;
  },
  async set(key, bucket) {
    // bucket = { tokens, updatedAt, expiresAt }
  },
  async delete(key) {}
};

Test

npm test

Publish to npm

  1. Create an npm account at https://www.npmjs.com/signup.
  2. Choose a unique package name in package.json. Search npm first because package names must be unique.
  3. Log in:
npm login
  1. Run tests:
npm test
  1. Preview the package contents:
npm pack --dry-run
  1. Publish:
npm publish --access public

For later updates, change the version and publish again:

npm version patch
npm publish --access public

Use minor for new features and major for breaking changes.

About

Easy rate limiter for your apps

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors