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

@baukit/auth-node

v0.3.0

Published

Node OIDC device authorization with S256 PKCE, refresh rotation, and a locked token cache.

Readme

@baukit/auth-node

@baukit/auth-node is the Node 24 OIDC device-flow package for CLI and MCP clients. It handles discovery, RFC 8628 polling, S256 PKCE, refresh rotation, and a local profile cache. It has no runtime dependencies.

The package does not print instructions or open a browser. Supply callbacks for those actions.

Device-flow client

import { DeviceFlowClient } from '@baukit/auth-node/device-flow';

const auth = new DeviceFlowClient(
  {
    issuer: process.env['OIDC_ISSUER'] ?? '',
    clientId: process.env['OIDC_CLIENT_ID'] ?? '',
    scopes: ['openid', 'profile', 'offline_access'],
    audience: 'notes-api',
    cache: {
      namespace: 'notes-mcp',
    },
  },
  {
    environmentToken: () => process.env['NOTES_API_TOKEN'],
  },
);

await auth.login({
  presentation: {
    showVerification: ({ verificationUri, userCode }) => {
      process.stderr.write(`Open ${verificationUri}\nEnter ${userCode}\n`);
    },
    showStatus: (status) => {
      process.stderr.write(`Login status: ${status}\n`);
    },
    openBrowser: (url) => openProductBrowser(url),
  },
});

const token = await auth.accessToken();

accessToken() checks the injected environment-token source first. It then reads the selected cache profile and refreshes near-expiry tokens. Refreshes share one promise in a process and hold an adjacent .lock file while reading and replacing the cache.

Pass an AbortSignal to login, accessToken, or logout. Discovery and token requests have a 15-second default timeout. A login has a 10-minute total timeout. Both limits are configurable.

Endpoint policy

The configured issuer must match discovery metadata. Put known issuer aliases in endpointPolicy.issuerAllowlist. Token and device endpoints must share the issuer origin and path. Put a provider's documented endpoint origin in endpointOriginAllowlist when it uses a separate origin.

All issuer, device, token, and verification URLs require HTTPS. Local development can set allowLoopbackHttp: true; this permits only localhost, 127.0.0.0/8, and ::1.

Discovery and token bodies are limited to 64 KiB by default. Errors contain a stable code, an allowlisted message, an optional HTTP status, and no provider body. The client does not log.

Cache contract

The JSON cache holds named profiles under one namespace. defaultTokenCachePath(namespace) resolves to $XDG_CONFIG_HOME/<namespace>/tokens.json, or ~/.config/<namespace>/tokens.json when XDG_CONFIG_HOME is unset.

On POSIX systems the cache file must have mode 0600 and its immediate directory must have mode 0700. Existing unsafe permissions fail with cache_permission. The cache rejects symlink path components. Writes use a new temporary file, sync it, and atomically rename it, so a write failure before rename leaves the old file intact. Windows skips POSIX mode checks and relies on host ACLs.

Use a separate namespace or profile for accounts that must not share credentials. logout() removes the selected profile and leaves other profiles in place.

Display-only claims

displayClaims() and decodeDisplayOnlyClaims() decode a small allowlist of JWT fields without checking the signature. Use the result only for labels such as a whoami display. Never use it for authorization, storage partitions, audit identity, or analytics identity.

Migration from product-local auth

Replace local discovery, device polling, refresh, and cache functions with one DeviceFlowClient. Keep these product inputs in the application:

  • environment variable names and defaults;
  • issuer, client ID, scopes, and audience;
  • CLI text and browser-launch behavior;
  • API base URL and bearer-token wiring; and
  • cache namespace, path, and profile selection.

Older product caches do not have the versioned profile document used here. Sign out or remove the old file, then run the product's login command once. The package intentionally does not guess which product-owned legacy shape it received.