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

@nextrush/security

v1.0.0

Published

Composite secure-by-default preset for NextRush — helmet + strict cookies + CSRF + rate limit in one call

Readme

@nextrush/security

One call that applies helmet, strict cookies, CSRF protection, and rate limiting together — the secure-by-default composite for apps that don't want to wire four packages by hand.

npm version types ESM only license

| | | | --- | --- | | Purpose | Composite secure-by-default preset — helmet + cookies + CSRF + rate limit in one call | | Package type | Middleware (composite) | | Status | Stable ✅ | | Included in nextrush? | ❌ No — install separately | | Runtime | Node (composed layers are per-adapter; see Compatibility) | | Requires | Node >=22 · ESM-only · TypeScript >=5.x | | Introduced | v1.0.0 |

Highlights

  • One call, four layers — helmet, cookies, CSRF, rate limit, applied in a fixed, safe order
  • Fails fast — every layer is built eagerly at construction, so an incomplete required option (CSRF's secret/session config) throws immediately, never on the first request
  • Per-layer overrides — pass options straight through to any layer without dropping the others
  • ESM-only, fully typed, zero any

The problem

Wiring a secure baseline by hand means importing four packages, remembering their interaction order (helmet before routes; CSRF after cookies are parsed; rate limiting before expensive work), and re-discovering each one's required configuration on your own:

// TODAY, without this package — four imports, and the order is on you to get right:
import { helmet } from '@nextrush/helmet';
import { cookies } from '@nextrush/cookies';
import { csrf } from '@nextrush/csrf';
import { rateLimit } from '@nextrush/rate-limit';

app.use(helmet());
app.use(cookies());
app.use(rateLimit());
const { protect } = csrf({ secret, getSessionIdentifier });
app.use(protect);

Nothing stops the order from drifting, and nothing tells you at a glance whether an app has all four layers or only two.

When to use

Use @nextrush/security if:

  • ✓ You want a secure baseline in one line, and are fine with the composed order (helmet → cookies → rate limit → CSRF).
  • ✓ Every layer's defaults, or straightforward per-layer overrides, meet your needs.

Reach for something else if:

  • ✗ You need a different layer order, or a layer this preset doesn't include (e.g. @nextrush/csp fine-tuning beyond what helmet exposes) → compose @nextrush/{helmet,cookies,csrf,rate-limit} directly.
  • ✗ You don't need CSRF (e.g. a pure JSON API with no cookie-based session) → security() still requires CSRF configuration, since it is the one layer with no safe zero-config default; compose the other three directly instead.

Installation

pnpm add @nextrush/security
# npm i @nextrush/security · yarn add @nextrush/security · bun add @nextrush/security

[!NOTE] Not included in the nextrush meta package — install it separately.

Quick start

import { createApp, listen } from 'nextrush';
import { security } from '@nextrush/security';

const app = createApp();

app.use(
  security({
    csrf: {
      secret: process.env.CSRF_SECRET!,
      getSessionIdentifier: (ctx) => ctx.state.sessionId as string,
    },
  })
);

listen(app, 8080);

Helmet's header set, cookie parsing, rate limiting, and CSRF protection are now all active — the only configuration required is CSRF's, because it is the one layer with no safe zero-config default.

Capabilities

Capabilities

  • Composite preset — one middleware combining helmet() + cookies() + rateLimit() + the CSRF protect middleware, in that fixed order
  • Eager construction — every layer builds at security() call time; a missing required option throws there, not on the first request

Developer experience

  • Per-layer overrides{ helmet, cookies, csrf, rateLimit } map directly onto each layer's own options type
  • Fully typed — strict TypeScript, zero any

Mental model

request ──▶ helmet ──▶ cookies ──▶ rateLimit ──▶ csrf.protect ──▶ your routes

Rule: the order is fixed and not configurable — security headers land before anything else runs, rate limiting runs before CSRF's cryptographic comparison, and CSRF runs last, immediately before your route handlers.

[!TIP] The full composition diagram is in ARCHITECTURE.md.


Common tasks

Override one layer without dropping the others

app.use(
  security({
    csrf: { secret, getSessionIdentifier },
    rateLimit: { max: 20, window: '1m' },
  })
);

Use in a JSON API with unbound CSRF (no session store yet)

app.use(
  security({
    csrf: { secret, sessionBinding: 'none' },
  })
);

API overview

| Export | Signature | Since | Stability | Description | | ------ | --------- | ----- | --------- | ----------- | | security | (options: SecurityPresetOptions) => Middleware | 1.0.0 | Stable ✅ | Builds the composite preset | | type SecurityPresetOptions | — | 1.0.0 | Stable ✅ | Per-layer configuration |

Options

| Option | Type | Required | Default | Security-sensitive | Description | | ------ | ---- | -------- | ------- | ------------------ | ----------- | | helmet | HelmetOptions | No | helmet's own defaults | — | Passed to helmet() | | cookies | CookieMiddlewareOptions | No | cookies' own defaults (secure: 'auto') | — | Passed to cookies() | | csrf | CsrfOptions | Yes | — | ⚠️ | Passed to csrf(); requires secret and either getSessionIdentifier or sessionBinding: 'none' | | rateLimit | RateLimitOptions | No | rate-limit's own defaults | — | Passed to rateLimit() |

Compatibility

Requirements

| Requirement | Version | | ----------- | ------- | | NextRush | 3.x | | Node.js | >=22 | | TypeScript | >=5.x |

Runtimes

| Runtime | Supported | Notes | | ------- | --------- | ----- | | Node.js >=22 | ✅ | ESM-only | | Bun / Deno / Edge | Depends on the composed layer | Each of helmet/cookies/csrf/rate-limit runs on every adapter; security() itself adds no platform-specific code |

Integration

  • Peer dependencies: @nextrush/core, @nextrush/cookies, @nextrush/csrf, @nextrush/helmet, @nextrush/rate-limit, @nextrush/types
  • Works with: any NextRush application (createApp())
  • Incompatible with: registering helmet()/cookies()/csrf()/rateLimit() a second time for the same concern — that duplicates headers/cookies/checks

[!IMPORTANT] NextRush is ESM-only, permanently — no CommonJS build. On Node >=22, CJS consumers can require() this ESM package natively. See the Module Format Policy.


Troubleshooting

Cause: security() builds csrf() eagerly, and CSRF has no safe zero-config default. Fix: supply csrf: { secret, getSessionIdentifier } (session-bound, recommended) or csrf: { secret, sessionBinding: 'none' } (unbound double-submit, intentional opt-in).

app.use(security({ csrf: { secret, getSessionIdentifier: (ctx) => ctx.state.sessionId } } ));

FAQ

Can I compose the four layers myself instead of using this preset? Yes — security() is a convenience composition, not a new capability. @nextrush/{helmet,cookies,csrf,rate-limit} remain independently usable and documented.

Why ESM-only? See the Module Format Policy.

Does it work on Bun / Deno / Edge? Each composed layer runs on every adapter; there's nothing platform-specific in security() itself.

Can I reorder the layers? No — the order (helmet → cookies → rate limit → CSRF) is fixed. Compose the four packages directly if you need a different order.


Package relationships

                 depends on            @nextrush/{core,helmet,cookies,csrf,rate-limit,types}
@nextrush/security ──────────────▶
                 often used with       @nextrush/session (once it ships — see RFC-032)
                 usually used next     none — this is typically the last security layer added

Architecture

Maintaining or contributing to this package? The internal design is in ARCHITECTURE.md. Design history: openspec/changes/harden-security-boundaries/design.md (D8).

Resources


MIT © Tanzim Hossain