npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@limitkit/nest

v1.0.0

Published

NestJS integration for LimitKit

Readme

LimitKit NestJS Adapter

npm version downloads license

Rate limiting for NestJS using LimitKit’s policy-driven engine.

This package:

  • ✅ integrates with NestJS seamlessly
  • ✅ allows you to override global rules for particular controllers or routes
  • ✅ returns 429 if the request is rejected
  • ✅ automatically sets standard IETF rate limit headers

⚡ Quick Start

npm install @limitkit/nest

Basic Setup

Simply call LimitModule.forRoot, provide the store and the rules.

All routes are now rate-limited globally.

import { Module } from "@nestjs/common";
import { LimitModule } from "@limitkit/nest";
import { InMemoryStore, InMemoryFixedWindow } from "@limitkit/memory";

@Module({
  imports: [
    LimitModule.forRoot({
      store: new InMemoryStore(),
      rules: [
        {
          name: "global",
          key: (req) => req.ip,
          policy: new InMemoryFixedWindow({
            name: "fixed-window",
            window: 60,
            limit: 100,
          }),
        },
      ],
    }),
  ],
})
export class AppModule {}

🎛 Route-Level Control

Override rules

Use @RateLimit() to override or extend global rules on a controller or route:

import { Controller, Get } from "@nestjs/common";
import { RateLimit } from "@limitkit/nest";
import { InMemoryFixedWindow } from "@limitkit/memory";

@Controller("api")
export class ApiController {
  @Get()
  @RateLimit({
    rules: [
      {
        name: "api",
        key: (req) => req.user.id,
        policy: new InMemoryFixedWindow({
          window: 60,
          limit: 50,
          name: "fixed-window",
        }),
      },
    ],
  })
  getData() {
    return { ok: true };
  }
}

🧠 Merge Behavior

Route-level rules are merged with global rules by name:

  • If a rule with the same name exists, it is overridden
  • If the name is new, it is appended

Example

Global:

rules: [
  { name: "global", key: "global", policy: ... },
  { name: "user", key: (req) => req.user.id, policy: ... },
]

Route:

@RateLimit({
  rules: [
    { name: "user", key: (req) => req.user.id, policy: stricterPolicy },
    { name: "route", key: "route", policy: ... },
  ],
})

Result:

[
  { name: "global", ... },        // unchanged
  { name: "user", ... },          // overridden by route rule
  { name: "route", ... },         // appended
]

Skip rate limiting

Simply add @SkipRateLimit decorator to a controller or route to bypass rate limits.

import { SkipRateLimit } from "@limitkit/nest";

@Controller()
export class HealthController {
  @Get("/health")
  @SkipRateLimit()
  health() {
    return { ok: true };
  }
}

If @SkipRateLimit is applied to a controller, but @RateLimit is applied to a route within it then the route will bypass all global limits and only the rules defined in the decorator are enforced.


Async Configuration (Redis, ConfigService, etc.)

Use forRootAsync when config depends on other providers:

import { Module } from "@nestjs/common";
import { LimitModule } from "@limitkit/nest";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { RedisStore, RedisFixedWindow } from "@limitkit/redis";
import { createClient } from "redis";

@Module({
  imports: [
    ConfigModule.forRoot(),
    LimitModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        const redis = createClient({
          url: config.get("REDIS_URL"),
        });

        await redis.connect();

        return {
          store: new RedisStore(redis),
          rules: [
            {
              name: "global",
              key: "global",
              policy: new RedisFixedWindow({
                window: 60,
                limit: 100,
                name: "fixed-window",
              }),
            },
          ],
        };
      },
    }),
  ],
})
export class AppModule {}

💉 Using RateLimiter in Services

You can inject the limiter directly in the module that imports LimitModule for custom contexts such as GraphQL, WebSockets, job queues:

import { Injectable } from "@nestjs/common";
import { RateLimiter } from "@limitkit/core";

@Injectable()
export class MyService {
  constructor(private limiter: RateLimiter) {}

  async doSomething(req) {
    const result = await this.limiter.consume(req);

    if (!result.allowed) {
      throw new Error("Rate limit exceeded");
    }
  }
}

📡 Headers

The guard provided by @limitkit/nest also automatically sets standard IETF rate limit headers for you:

RateLimit-Limit
RateLimit-Remaining
Retry-After (when 429)

Along with that, the guard also sets a custom header:

Reset-After

which is the seconds after which the limit fully resets.

Example:

RateLimit-Limit: 100
RateLimit-Remaining: 0
Reset-After: 60
Retry-After: 30