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

@youneed/server-middleware-api-key

v0.1.0

Published

@youneed/server middleware: shared-secret API key auth (header/query/scheme), SHA-256 matched, principal mapping.

Readme

@youneed/server-middleware-api-key

Shared-secret API key authentication for @youneed/server. The simplest auth tier: the client presents a pre-issued secret key and it's matched against a configured set — optionally mapped to a principal/scope. No structure, no signature, no expiry — "knows the secret ⇒ allowed". Best for service-to-service / integration callers. Always run it over TLS.

import { Application } from "@youneed/server";
import { apiKey } from "@youneed/server-middleware-api-key";

// Flat allowlist (key sent as `X-API-Key: <key>`):
app.use(apiKey({ keys: [process.env.PARTNER_KEY!] }));

// Keys mapped to a principal → ctx.state.apiClient:
app.use(apiKey({ keys: { k_live_abc: { name: "billing", scopes: ["read"] } } }));

// Store only HASHES at rest (never plaintext keys):
app.use(apiKey({ hashed: true, keys: [sha256hex(process.env.PARTNER_KEY!)] }));

// Dynamic lookup (DB / cache):
app.use(apiKey({ verify: async (key) => db.clientByKey(key) }));

Where the key comes from

By default the X-API-Key header. You can additionally accept it from a query parameter or an Authorization scheme:

apiKey({ keys, header: "x-api-key", query: "api_key", scheme: "ApiKey" });
// X-API-Key: k…   |   ?api_key=k…   |   Authorization: ApiKey k…

Matching & storage

Keys are matched by SHA-256 digest, not raw compare: the presented key is hashed, then looked up in a table. This is constant-time-safe (preimage resistance protects the secret — no per-character comparison against it) and lets you store only digests via hashed: true.

API key vs bearer / jwt / authorization

| | api-key | bearer | jwt / authorization | | --- | --- | --- | --- | | Token | opaque shared secret | opaque token | signed, self-contained | | Verify | match a set / lookup | your verify callback | signature + claims | | Lifetime | typically long-lived, manual rotation | per session | exp in token | | Who | a service/integration | a user/session | a user/session |

It's "password login for machines". Use it for partner/integration access; reach for jwt/authorization when you need signed, expiring, user-bound tokens.

Options

| option | meaning | | --- | --- | | keys | Allowlist (string[]) or key → principal map. With hashed ⇒ SHA-256 hex. | | verify | Dynamic (key, ctx) => principal \| false (DB lookup). | | header | Key header (default "x-api-key"). | | query | Also accept the key from this query param. | | scheme | Also accept Authorization: <scheme> <key>. | | hashed | keys entries are SHA-256 hex digests of the real keys. | | stateKey | Where to put the principal (default "apiClient"). | | optional | Let keyless requests through. | | status | Status for a rejected request (default 401). |