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

@filamentjs/rate-limiting

v0.1.0

Published

Named multi-bucket rate limiting for FilamentJS

Readme

@filamentjs/rate-limiting

Named, caller-specific rate-limit buckets with multiple simultaneous fixed windows. Endpoints can share a bucket, use independent cost groups, or atomically charge several buckets in one request.

Key features

  • Named endpoint buckets shared across routes, with per-endpoint request cost.
  • Multiple fixed-window limits and plan-specific quota definitions per bucket.
  • Trusted subject and plan resolver hooks plus secure missing-identity failure.
  • Bounded standalone state and an optional atomic server-time Redis adapter.
  • All-or-none multi-bucket accounting with explicit 401, 429, and 503 behavior.

Quick start

npm install @filamentjs/rate-limiting filamentjs
import { createApp, type ContextMeta as BaseContext, type FrameworkMeta } from "filamentjs";
import {
  createStandaloneStore,
  setup,
  type AppMeta,
  type ContextMeta,
} from "@filamentjs/rate-limiting";

const store = createStandaloneStore({ maxEntries: 100_000 });
const app = createApp<FrameworkMeta & AppMeta, BaseContext & ContextMeta>(
  { application: { maxRequestSize: "1MiB" } },
  {},
);
setup(app, {
  store,
  defaultPlan: "basic",
  plans: {
    basic: {
      buckets: {
        groupA: { limits: [{ id: "second", capacity: 100, windowSeconds: 1 }] },
        groupB: { limits: [{ id: "second", capacity: 5, windowSeconds: 1 }] },
      },
    },
  },
  resolveSubject: () => "replace-with-authenticated-subject",
});
app.get(
  "/expensive",
  { rateLimiting: { buckets: [{ name: "groupB", cost: 1 }] } },
  async (_req, res) => res.json({ ok: true }),
);
// On shutdown: await app.close(); await store.close();

Requires Node 24+ and the exact supported peer [email protected].

How it works and options

Endpoints sharing groupA share its quota for the same subject; groupB remains independent, and one request may atomically charge both.

The standalone store is bounded, single-process, non-durable, and uses fixed windows. Rejected multi-limit attempts consume no quota, so a failed batch never partially charges another bucket. Operators must synchronize participating host clocks. This policy is not designed to maintain rate-limit consistency across large geographic distances, and it makes no millisecond-precision claim.

Storage and configuration errors fail closed with 503 unless an endpoint explicitly chooses failOpen. Missing subject/plan fails closed with 401. resolvePlan(req) takes precedence over endpoint/default plan selection, which allows an earlier authentication policy to place user/subscription data in context. No forwarding header is trusted as identity by default.

Draft warning: RateLimit-Policy and RateLimit use draft-ietf-httpapi-ratelimit-headers-11 (May 2026), a work in progress that may change. The wire serializer is isolated from store decisions. Rejections also send Retry-After and the draft quota-exceeded problem shape.

Redis is optional. @filamentjs/redis includes a server-time Lua adapter through the structural atomic RateLimitStore contract. Its contention and expiry suite passes against Redis 6.2.23. It is not yet advertised as distributed-production-ready because reconnect, ambiguous-failure, and cluster deployment tests remain. Do not substitute a non-atomic GET/SET implementation.

Public API

| Surface | Meaning | | --- | --- | | setup(app, options) | Registers the quota middleware once. | | createStandaloneStore(options?) | Creates bounded, local fixed-window state. | | RateLimitStore | Structural atomic backend contract implemented by @filamentjs/redis. | | AppMeta.rateLimiting | false, or endpoint buckets, costs, optional plan, and failOpen. | | ContextMeta.rateLimiting | Effective plan, subject, and immutable decision. |

The middleware runs before the route and can stop with 401, 429, or 503. It does not transform response bodies and works with buffered or streaming routes. Authenticate before identity-based resolution; use a deliberately safe pre-authentication subject if limiting expensive authentication itself. Unknown plans/buckets and invalid costs fail securely.

Development and demo

From a source checkout:

npm test
npm run example
npm run demo

The unattended demo makes three live requests against a two-request window, prints draft rate-limit fields and bodies, demonstrates the terminal 429, then closes the server/store and exits. There is no pre-0.1 migration contract.

License

ISC