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

@developer.krd/nexura

v0.2.0

Published

Nexura backend protection for Node.js — request firewall (WAF), file/code integrity, config & dependency auditing, with live reporting to the Nexura dashboard.

Readme

@developer.krd/nexura

Backend security for Node.js, by Nexura.

One dependency-free package that sits in front of your app and:

  • Blocks attacks at the request layer — a signature WAF for SQL injection, XSS, path traversal, command injection, and known scanner tooling
  • Hardens response headers and strips server banners
  • Rate-limits abusive clients per IP
  • Audits your deployment continuously — file permissions, leaked keys, code integrity, configuration, and dependencies
  • Reports everything to your Nexura dashboard, and takes its enforcement settings back from it live

Zero runtime dependencies. Node ≥20. ESM. Ships TypeScript types.

npm install @developer.krd/nexura

Get an API key from clients.developer.krd → your site → Backend → API Keys.


Quick start

Express

import express from "express";
import { createNexura } from "@developer.krd/nexura";

const app = express();
app.use(express.json());          // mount the body parser first so the WAF can see bodies

const nexura = createNexura({ apiKey: process.env.NEXURA_API_KEY });
app.use(nexura.express());        // headers → rate limit → WAF

Shorthand:

import { nexuraExpress } from "@developer.krd/nexura/express";
app.use(nexuraExpress({ apiKey: process.env.NEXURA_API_KEY }));

Fastify

import { nexuraFastify } from "@developer.krd/nexura/fastify";
await app.register(nexuraFastify, { apiKey: process.env.NEXURA_API_KEY });

Fastify is inspected in two passes: onRequest covers the path, query, and headers before any body is read; preHandler inspects the parsed body. Rate limiting is applied once, on the first pass.

Any framework

inspect() is pure — no I/O, no reporting, no side effects. Use it anywhere:

import { createNexura } from "@developer.krd/nexura";
const nexura = createNexura({ apiKey: process.env.NEXURA_API_KEY });

const verdict = nexura.inspect({
  method: req.method,
  path: req.url,
  headers: req.headers,
  query: req.query,
  body: req.body,
  ip: req.socket.remoteAddress,
});

if (verdict.blocked) {
  console.warn(verdict.type, verdict.rule);   // e.g. "sql_injection"
  return res.writeHead(403).end("Forbidden");
}

Configuration

| Option | Default | Description | |---|---|---| | apiKey | NEXURA_API_KEY | Your nxr_… key. Without it the SDK runs local-only and reports nothing. | | siteId | NEXURA_SITE_ID | Public site id (nex_…). Not needed for site-scoped keys. | | apiOrigin | NEXURA_API_ORIGIN or https://clients.developer.krd | Dashboard origin. | | mode | follow dashboard | "block" or "report" to override enforcement locally. | | rateLimit | { max: 300, windowMs: 60000 } | Per-IP sliding window, or false to disable. | | trustProxy | false | Read the client IP from X-Forwarded-For. | | appDir | process.cwd() | Root directory the audits scan. | | skipPaths | [] | Paths the WAF must not inspect. Strings match as a prefix, RegExps are tested. | | allowIps | [] | IPs that bypass the WAF and rate limiter entirely. | | denyIps | [] | IPs refused before any other check. | | configRefreshMs | 900000 (15 min) | How often to re-read settings from the dashboard. 0 = fetch once at boot. | | handleSignals | false | Flush telemetry and stop timers on SIGINT/SIGTERM. | | disableAudit | false | Turn off the background audit (.audit() still works). | | disableHealth | false | Turn off periodic health pings. | | silent | false | Silence the SDK's own console output. | | onThreat | – | (threat) => void, called for every detection. | | onConfigChange | – | (next, previous) => void, called when dashboard settings change. | | onAudit | – | (result) => void, called after each background audit. |

Avoiding false positives

A signature WAF cannot tell a SQL injection attempt from a legitimate request that contains SQL. If you have endpoints that accept queries, markdown, HTML, or raw logs, exclude them — otherwise real traffic gets 403s:

createNexura({
  apiKey: process.env.NEXURA_API_KEY,
  skipPaths: [
    "/admin/query-console",     // prefix match
    "/api/import",
    /^\/webhooks\//,            // regexp
  ],
  allowIps: ["10.0.0.5"],       // internal health checkers, CI runners
});

Excluded requests are skipped entirely: they cannot be blocked, are not reported, and do not consume rate-limit budget.


What the WAF detects

inspect() decodes the path, flattens the query object, and scans up to 8 KB of the body, most-severe-first. The first match wins.

| Type | Severity | Catches | |---|---|---| | sql_injection | critical | UNION SELECT, OR 1=1, stacked DROP/ALTER, sleep()/benchmark() time delays, information_schema probing, trailing comments | | command_injection | critical | Shell metacharacters before cat/curl/wget/nc/bash, $(…), backtick substitution, pipes into interpreters | | path_traversal | high | ../ sequences, encoded %2e%2e, /etc/passwd, C:\Windows\, file://, /proc/self/environ | | xss_attempt | high | <script>, javascript: URLs, inline on*= handlers, <iframe>, document.cookie, <svg onload> | | bad_bot | high | sqlmap, nikto, nmap, masscan, nessus, acunetix, netsparker, wpscan, gobuster, dirbuster, hydra | | rate_limit | medium | More than max requests per window from one IP |

Rules are deliberately conservative, aimed at low false positives on real API traffic.

Response headers

Applied to every response; headers your app already set are left alone.

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin-Opener-Policy: same-origin

X-Powered-By and Server are stripped.

What the audit checks

Runs shortly after boot, then every 6 hours, and on demand via nexura.audit() or the CLI. Produces a 0–100 score — each failing check subtracts by severity (critical 30, high 15, medium 7, low 2).

Files & permissions — world-writable files, .env/secret files readable by others, private keys committed into the project (.pem, .key, .pfx, .p12, .jks), sensitive files sitting inside a public directory (public/, static/, www/, dist/, build/), and private-key blocks embedded in config/text files.

Code integrity — SHA-256 manifest of your source (.js .mjs .cjs .ts .mts .cts .jsx .tsx .json .env .sh .sql) compared against a baseline in .nexura/manifest.json. Flags files changed, added, or removed since the baseline. node_modules, .git, and build output are excluded.

Configuration & database — NODE_ENV not production, DEBUG left enabled, NODE_TLS_REJECT_UNAUTHORIZED=0 (certificate validation disabled), weak or default database passwords in DATABASE_URL/POSTGRES_URL/MONGODB_URI/REDIS_URL and friends, and short SESSION_SECRET/JWT_SECRET/COOKIE_SECRET values.

Dependencies — missing package.json or lockfile, packages with known advisories, risky packages, and unpinned version ranges.


CLI

Installed as the nexura bin:

npx nexura init            # seed the code-integrity baseline
npx nexura audit           # run every audit and print the report
npx nexura audit --send    # …and upload it to the dashboard
npx nexura verify          # integrity-only check
npx nexura doctor          # key, connectivity, and environment
npx nexura status          # what settings the dashboard is serving this key

Without installing first, use the full name: npx @developer.krd/nexura audit --send.

Exit codes

| Code | Meaning | |---|---| | 0 | Clean | | 1 | Usage or connectivity error | | 2 | audit: a high/critical problem was found · verify: code changed since baseline |

Which makes it a CI gate:

- run: npx nexura verify     # fails the build if deployed code was tampered with
- run: npx nexura audit --send

Commit .nexura/manifest.json to version control so tampering is detectable across deploys.


Dashboard integration

Telemetry is buffered and POSTed as NDJSON to /api/nexura/server/ingest every 5 seconds (or immediately at 50 events), authenticated with your API key.

| Event | Sent when | Shows up as | |---|---|---| | server_threat | Every WAF or rate-limit detection | Threats, with rule, path, severity, and whether it was blocked | | server_audit | After each audit | Server score and grouped findings | | server_health | Every 60s | "Connected" state, Node version, uptime, RSS, requests inspected/blocked |

High and critical threats also trigger your configured notification channels.

Settings flow back, live

At boot — and every 15 minutes after — the SDK re-reads /api/nexura/server/config. Changing your plan or toggling enforcement in the portal reaches running servers without a restart:

createNexura({
  apiKey: process.env.NEXURA_API_KEY,
  configRefreshMs: 5 * 60 * 1000,
  onConfigChange: (next, prev) => {
    logger.info({ was: prev.enforce, now: next.enforce }, "nexura enforcement changed");
  },
});

Call await nexura.refreshConfig() to pull immediately.

Enforcement follows your plan

Plans with backend protection block; free and report-only plans record without blocking, so you can see exactly what would have been stopped before turning it on. mode overrides both:

createNexura({ mode: "report" });   // observe only, whatever the plan says
createNexura({ mode: "block" });    // enforce locally

Health pings are always accepted so the dashboard shows your server as connected, even on a report-only plan.


Runtime API

const nexura = createNexura({ /* … */ });

nexura.inspect(request)      // pure verdict, no side effects
nexura.express()             // Express middleware
nexura.fastify               // Fastify plugin
await nexura.audit()         // run + report an audit now
nexura.reportThreat({ … })   // report a detection from your own code
await nexura.refreshConfig() // re-read dashboard settings now
nexura.status()              // live snapshot
nexura.config                // effective runtime config
nexura.enforcing             // true when blocking
nexura.version
await nexura.destroy()       // flush and stop all timers

Your own health endpoint

app.get("/internal/security", (req, res) => res.json(nexura.status()));
{
  "version": "0.2.0",
  "reporting": true,
  "connected": true,
  "enforcing": true,
  "config": { "enforce": true, "audits": true, "healthIntervalMs": 60000, "auditIntervalMs": 21600000 },
  "requestsInspected": 18402,
  "requestsBlocked": 37,
  "lastConfigAt": "2026-08-07T10:15:04.881Z"
}

Feeding your own logging

createNexura({
  onThreat: (t) => logger.warn({ type: t.type, rule: t.rule, path: t.path, blocked: t.blocked }, "attack"),
  onAudit: (r) => logger.info({ score: r.score }, "nexura audit"),
});

Shutdown

createNexura({ handleSignals: true });   // flush on SIGINT/SIGTERM
// or wire it yourself:
process.on("SIGTERM", () => nexura.destroy().then(() => process.exit(0)));

Operational notes

Fail-open by design. Every hook is wrapped — reporting failures, audit errors, and callback exceptions never propagate into your request path. If the dashboard is unreachable, telemetry is retried a few times, then dropped rather than growing unboundedly. Your app keeps serving.

Behind a proxy. Set trustProxy: true, or every client looks like your load balancer — which breaks per-IP rate limiting and makes allowIps/denyIps useless.

Multiple instances. The rate limiter is in-memory and per-process, so N instances allow roughly N × max. Size accordingly, or rely on your edge/CDN limiter for a global bound.

Timers are unref'd. Nothing the SDK schedules will keep your process alive.

Privacy. Raw client IPs are never transmitted. They are hashed with SHA-256 plus a daily-rotating salt, matching the dashboard's own scheme, so an address cannot be recovered and correlation across days is not possible.

Body inspection is capped at 8 KB of scanned text per request, so large uploads don't become a CPU cost.

TypeScript

import { createNexura } from "@developer.krd/nexura";
import type {
  NexuraConfig, NexuraStatus, WafVerdict, ThreatReport,
  AuditResult, AuditFinding, ServerConfig, Severity, ServerThreatType,
} from "@developer.krd/nexura";

Subpath exports: @developer.krd/nexura/express, @developer.krd/nexura/fastify.

MIT © developer.krd