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

knowless

v1.3.2

Published

Small, opinionated, full-stack passwordless auth for Node.js services that don't need to email their users for anything but the sign-in link.

Readme

knowless

Small, opinionated, full-stack passwordless auth for Node.js services that don't need to email their users for anything but the sign-in link.

npm install knowless

v1.0.0 (walk-away release) | Node.js >= 22.5 | 1 production dep (nodemailer)

What it does

The simpler answer that always worked: magic link in, session cookie out, nothing else stored. Email is HMAC-hashed at the boundary and discarded. The library refuses, by API shape, to send anything but the sign-in link or store anything identifying.

Most auth libraries default to maximum identity collection: full email in plaintext, profile fields, recovery email, federation. Even nominally privacy-focused options store enough that a breach is materially harmful. knowless inverts the default.

The thesis: most services have ten layers of auth tooling where they need two.

How it works

email  →  HMAC-SHA256(secret, normalize(email))  →  opaque handle
            |                                         |
            v                                         v
       magic-link token (256-bit, single-use)    sessions, tokens
            |                                         |
            v                                         v
       submitted via localhost SMTP             stored as SHA-256 hashes
            |
            v
       user clicks  →  handle resolved  →  signed cookie set
  • Plaintext email is never persisted. Only the salted hash (HMAC-SHA256(secret, normalized_email)).
  • Only the magic link is ever sent. No welcome, no digest, no notification. There is no API to send anything else.
  • All outbound mail goes via your localhost MTA. No vendor SDKs, no API tokens.
  • Tokens are SHA-256 at rest, single-use, 15-min TTL. Raw token never persisted.
  • Session cookies are HMAC-signed. No JWT, no algorithm confusion.
  • Sham work on every miss. Unknown emails do the same work as registered ones (compose, submit, log) but the SMTP recipient is a null-route. Times equivalent within 1ms — measured in CI.

Two modes

Same library, two flows. They coexist in one app — pick per action.

  • "Sign in, then do the thing" — a normal login.
  • "Do the thing, confirm by email" — drop a pin, post a comment, share a link without an account, and the email confirmation creates the account in the background.

The same sham-work flow runs underneath either mode, so unknown emails, rate-limit hits, and real sends look identical to an external observer.

Two deployment shapes

| Shape | When | |---|---| | Library mode | Mount the five handlers (login, callback, verify, logout, loginForm) in your existing Node app. | | Standalone server (npx knowless-server) | Forward-auth gateway behind Caddy / nginx / Traefik for self-hosters gating Uptime Kuma / AdGuard / Pi-hole / Sonarr / Jellyfin / etc. One auth subdomain, SSO across services via the parent-domain cookie. |

What knowless refuses (by design)

These are closed doors, not omissions. If any break your case, knowless isn't the right tool — look at Lucia, Auth.js, or commercial offerings.

  • Localhost SMTP only. No Mailgun / Postmark / SES / Resend. Vendor relationships invite reusing the mailer for non-auth mail, which collapses the "one mail purpose" invariant.
  • One mail purpose: the sign-in link. No sendNotification() to be tempted by.
  • Plain-text 7-bit email. No HTML, no tracking pixels, no click-rewriting, no read-receipts.
  • No DKIM/SPF in the library. That's the MTA's job; knowless emits clean RFC822 and your Postfix + opendkim signs it.
  • No OAuth / OIDC / SAML. Different audience.
  • No 2FA / WebAuthn / TOTP / passkeys. Compose with a separate library if you need them.
  • No admin UI. sqlite3 knowless.db is the admin UI.
  • Hardcoded login form. Templating is a slope — today "let me put my logo," tomorrow "let me theme the page," eventually "let me embed a JS framework." Fork, override the route entirely, or live with it.
  • No telemetry, analytics, or error reporting. No phone-home of any kind. Operator-side observability is opt-in via three hooks (onMailerSubmit / onTransportFailure / onSuppressionWindow) — wire them or be silent.
  • Walks away at v1.0.0. Maintenance mode after that — security fixes, bug fixes that don't change the API surface, doc fixes, helper exports.

Operator commitments

By choosing knowless, you commit to running:

  • Postfix (or another MTA) on the same host, outbound-only
  • SPF, DKIM, PTR records for your sending domain
  • Outbound port 25 open (some clouds block it)
  • A null-route for the configured shamRecipient so silent-miss sham mail drops, not bounces

Threat model — one paragraph

Email-based magic links are exactly as strong as the user's mailbox. knowless can harden the auth flow; it cannot harden an inbox the user has already lost. The list below reflects that boundary.

Defends well: DB-only leaks (handles are HMAC-salted), plaintext-email exfiltration (none persisted), password reuse (no passwords), silent email enumeration via the login form (timing- equivalent + same response shape), email-bombing a target (per-handle token cap), naive bots (honeypot), account-creation spam (per-IP caps), replay attacks (atomic mark-token-used), open redirects (next_url whitelist), CSRF on POST endpoints (Origin/Referer whitelist).

The per-IP defences key on the client IP. Behind a reverse proxy you must forward the real client IP, or they collapse to a single bucket and stop biting per-attacker — see GUIDE (proxies / startLogin) and OPS (nginx).

Partially: HMAC-secret-only leak (allows targeted existence checks but not session forgery), phishing (no password to type into a fake site, but a phished mailbox still receives links).

Does NOT defend against: compromised email accounts (the magic link is a bearer token — anyone who can read the inbox can use it; defense lives at the email provider, not in this library), sophisticated bots that bypass the honeypot, distributed floods from many IPs, full server compromise, social engineering, insider threat at the operator. Layer-2 defences (Cloudflare, fail2ban, reverse-proxy rate-limits) belong above the library. Note the per-IP caps bound a single address, not aggregate outbound volume — under a distributed flood (many IPs, each under the cap) your sender-domain reputation, the asset this auth channel depends on, is the perimeter's responsibility, not the library's.

Adopters

Production users of knowless, in adoption order:

  • addypin — pin-drop location sharing. First knowless adopter; Mode A (drop-pin-then-confirm).
  • plato — forum (Reddit-shaped, one fingerprint per site). Mode B (sign-in-then-do).
  • gitdone — multi-party email workflows verified via DKIM/SPF inbound. Mode A (start-workflow-then-confirm).

If you're picking knowless up: the addypin and gitdone callsites are both Mode A and good worked references for the use-first / claim-later shape.

Going further

  • GUIDE.md — integration walkthrough, observability hooks, edge cases, FAQ, troubleshooting.
  • OPS.md — operator setup (Postfix install, SPF/DKIM/PTR/ DMARC at your registrar, null-route, systemd, forward-auth wiring, fail2ban).
  • CHANGELOG.md — version history.

License

Apache 2.0 with NOTICE preservation. Forks must keep the NOTICE file.