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

@namoidhq/js

v3.2.0

Published

Core JavaScript SDK for NamoID Hosted Auth using OpenID Connect Authorization Code with PKCE.

Readme

@namoidhq/js

Core JavaScript SDK for NamoID Hosted Auth using OpenID Connect Authorization Code with PKCE.

npm i @namoidhq/js

Start hosted sign-in

import { createNamoIDClient } from "@namoidhq/js";

const namoid = createNamoIDClient({
  clientId: "namoid_client_live_...",
});

const started = await namoid.hostedAuth.start({
  redirectUri: "https://your-app.com/auth/callback",
});

// Retain this one-time transaction until the callback. Do not store tokens here.
sessionStorage.setItem("namoid_transaction", JSON.stringify(started.transaction));
window.location.assign(started.authorizationUrl);

The Client ID resolves the correct issuer and Hosted Auth domain. The SDK then uses issuer discovery instead of hard-coded OAuth endpoints.

Complete a public-client callback

const transaction = JSON.parse(sessionStorage.getItem("namoid_transaction")!);
const callback = new URL(window.location.href);

if (callback.searchParams.get("state") !== transaction.state) {
  throw new Error("Invalid authorization state");
}

const tokens = await namoid.hostedAuth.exchangeCode({
  code: callback.searchParams.get("code")!,
  redirectUri: transaction.redirectUri,
  codeVerifier: transaction.codeVerifier,
});

const identity = await namoid.hostedAuth.userInfo(tokens.access_token);
sessionStorage.removeItem("namoid_transaction");

For browser apps, prefer @namoidhq/react, which validates state, response issuer, the signed ID token, nonce, and the UserInfo subject. Do not persist bearer or refresh tokens in localStorage or sessionStorage.

For confidential Next.js apps, use @namoidhq/nextjs so the Client Secret, PKCE verifier, callback validation, refresh token, and application session remain server-side.

Hosted sign-in in a popup

Popup delivery uses the same OIDC Authorization Code + PKCE flow. Register a same-origin callback such as https://your-app.com/auth/namoid/popup and render this minimal bridge on that route:

import { relayHostedAuthPopupCallback } from "@namoidhq/js";

relayHostedAuthPopupCallback();

Then open Hosted Auth from a direct user click:

const result = await namoid.hostedAuth.popup({
  redirectUri: `${window.location.origin}/auth/namoid/popup`,
  // Optional: identityProvider: "google",
  // Optional: authenticationMethod: "passkey", "password", "email_otp",
  // "magic_link", or "phone_otp",
});

const tokens = await namoid.hostedAuth.exchangeCode({
  code: result.code,
  redirectUri: result.transaction.redirectUri,
  codeVerifier: result.transaction.codeVerifier,
});

The SDK binds the callback to a random, same-origin per-popup channel and validates callback origin, state, and issuer. It also verifies the exact popup handle when the browser preserves window.opener. The bridge relays only the code, state, issuer, or a bounded OAuth error—never tokens or profile data. If a browser blocks the popup, catch popup_blocked and offer a fresh normal full-page redirect.

identityProvider selects a configured social provider. authenticationMethod selects a configured hosted passkey, password, email-code, magic-link, or phone-code ceremony. All remain ordinary OIDC Authorization Code + PKCE requests; provider credentials, passwords, OTPs, and WebAuthn challenges never move into the relying-party DOM.

namoid.auth.getConfig() includes sign_in_choices, which tells UI adapters whether each configured choice uses a native_challenge or a browser_redirect. Consume this field instead of inferring delivery from a method name. The older method and provider lists remain available for compatibility with earlier NamoID deployments.

Custom SPA UI with native email OTP (Test preview)

Native email OTP is a guarded Test-only preview for trusted first-party SPA applications provisioned for the preview. It is not a general Console setting. Read turnstile_site_key and native_auth_turnstile_actions from namoid.auth.getConfig() and obtain a fresh Turnstile token for each protected step.

const started = await namoid.nativeAuth.start({
  redirectUri: `${window.location.origin}/auth/callback`,
  turnstileToken: startTurnstileToken,
});

await namoid.nativeAuth.requestEmailOtp({
  flowToken: started.flowToken,
  email,
  turnstileToken: otpTurnstileToken,
});

const authorization = await namoid.nativeAuth.verifyEmailOtp({
  flowToken: started.flowToken,
  email,
  code,
  transaction: started.transaction,
});

const tokens = await namoid.hostedAuth.exchangeCode({
  code: authorization.code,
  redirectUri: started.transaction.redirectUri,
  codeVerifier: started.transaction.codeVerifier,
});

Social login, passkeys, MFA, waitlists, custom registration fields, and mobile native clients continue through Hosted Auth. Do not store bearer or refresh tokens in browser storage.

Docs: https://docs.namoid.in · Contact: [email protected]

License

MIT © PolyMindsLabs Pvt. Ltd.