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

@grasp-labs/ds-auth-web

v0.7.0

Published

Modern authentication library for React applications with OAuth2, credentials, token sessions, and HTTP-only cookie sessions.

Readme

@grasp-labs/ds-auth-web

Modern authentication library for React applications with OAuth2, credentials, token sessions, and HTTP-only cookie sessions.

Installation

npm install @grasp-labs/ds-auth-web

For beta releases:

npm install @grasp-labs/ds-auth-web@beta

Quick Start

import { AuthProvider, useAuth } from "@grasp-labs/ds-auth-web";

function App() {
  return (
    <AuthProvider
      storageType="sessionStorage"
      authMode="cookie"
      autoRefresh={false}
      credentials={{
        loginUrl: "/api/auth/login",
        mfaUrl: "/api/auth/mfa",
        userInfoUrl: "/api/auth/me",
        logoutUrl: "/api/auth/logout",
      }}
      oauth2={{
        google: {
          clientId: "your-google-client-id",
          redirectUri: window.location.origin,
          authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
          tokenUrl: "https://oauth2.googleapis.com/token",
          scope: ["openid", "profile", "email"],
        },
      }}
    >
      <YourApp />
    </AuthProvider>
  );
}

function YourApp() {
  const { isAuthenticated, user, loginOAuth2, loginWithCredentials, logout } =
    useAuth();

  if (isAuthenticated) {
    return (
      <div>
        Welcome, {user?.name}!<button onClick={logout}>Sign Out</button>
      </div>
    );
  }

  return (
    <div>
      {/* Credentials login */}
      <form
        onSubmit={(e) => {
          e.preventDefault();
          const form = e.currentTarget;
          const formData = new FormData(form);
          loginWithCredentials({
            email: String(formData.get("email") ?? ""),
            password: String(formData.get("password") ?? ""),
          });
        }}
      >
        <input name="email" type="email" required />
        <input name="password" type="password" required />
        <button type="submit">Sign In</button>
      </form>

      {/* OAuth2 login with provider key */}
      <button onClick={() => loginOAuth2("google")}>Sign in with Google</button>
    </div>
  );
}

Features

  • 🔐 OAuth2 with PKCE - Secure authorization code flow
  • 📝 Credentials login - Email/password with MFA support
  • 🍪 HTTP-only cookie sessions - BFF-friendly session mode without exposing tokens to React
  • 🔄 Auto token refresh - Keeps sessions alive automatically
  • 💾 Flexible storage - Session, local, or memory storage
  • 🎣 React 19 ready - No unnecessary hooks or memoization
  • 🌐 CORS support - Built-in CORS handling for credentials auth
  • 🔌 Axios integration - Auto-inject auth headers with one flag
  • 🛡️ Error handling - Typed errors with user-friendly messages
  • 📦 Small bundle - ~25KB gzipped
  • 🚀 TypeScript - Full type safety

API Reference

useAuth() Hook

The main hook for accessing authentication state and methods:

const {
  // State
  isAuthenticated: boolean,
  user: User | null,
  tokens: Tokens | null,
  method: 'oauth2' | 'credentials' | null,
  error: Error | null,
  mfa: MFAState | undefined,
  hasCheckedSession: boolean,

  // Loading states
  isLoggingIn: boolean,
  isVerifyingMFA: boolean,
  isRefreshing: boolean,
  isFetchingUserInfo: boolean,

  // Methods
  loginOAuth2: (providerKey: string) => Promise<void>,
  loginWithCredentials: ({ email, password, rememberMe }) => Promise<Tokens | { mfaRequired: true } | void>,
  verifyMFA: (code: string) => Promise<Tokens | void>,
  logout: () => Promise<void>,
  refresh: () => Promise<boolean>,

  // Utilities
  getAuthHeader: () => string | null,
} = useAuth();

Configuration

AuthProvider accepts individual props instead of a config object:

interface IAuthProviderProps {
  children: ReactNode;

  // Storage
  storageType?: "localStorage" | "sessionStorage" | "memory"; // Default: "sessionStorage"

  // Session mode
  authMode?: "token" | "cookie"; // Default: "token"

  // Auto refresh
  autoRefresh?: boolean; // Default: true
  refreshBuffer?: number; // Buffer before expiry in seconds
  refreshInterval?: number; // Check interval in ms

  // OAuth2 providers
  oauth2?: Record<string, OAuth2Config>;

  // Credentials configuration
  credentials?: CredentialsConfig;

  // Callbacks
  onAuthChange?: (isAuthenticated: boolean) => void;
  onError?: (error: Error) => void;
}

interface OAuth2Config {
  clientId: string;
  redirectUri: string;
  authorizationUrl: string;
  tokenUrl: string;
  userInfoUrl?: string;
  scope?: string[];
  clientSecret?: string;
  usePKCE?: boolean; // Default: true
  revokeUrl?: string;
  refreshTokenUrl?: string;
}

interface CredentialsConfig {
  loginUrl: string;
  mfaUrl?: string;
  userInfoUrl?: string;
  refreshUrl?: string;
  logoutUrl?: string;
  cors?: boolean;
}

HTTP-only Cookie Sessions

Use authMode="cookie" when a backend-for-frontend owns the session and stores tokens in HTTP-only cookies. In this mode:

  • loginWithCredentials sends x-auth-mode: cookie and withCredentials: true.
  • the backend should set its session cookies and can return 204 No Content;
  • frontend tokens remain null;
  • AuthProvider restores an existing browser session by calling credentials.userInfoUrl with credentials when it starts with no local user;
  • hasCheckedSession becomes true once that startup check completes or is skipped;
  • a 401 from credentials.userInfoUrl leaves the user unauthenticated without logging noisy errors.

That bootstrap is useful after a credentials login, an SSO/OIDC callback handled by the BFF, a page reload, or navigation between React apps sharing the same cookie session.

<AuthProvider
  authMode="cookie"
  autoRefresh={false}
  credentials={{
    loginUrl: "/api/auth/login",
    mfaUrl: "/api/auth/mfa-login",
    userInfoUrl: "/api/me",
    logoutUrl: "/api/auth/logout",
  }}
>
  <App />
</AuthProvider>

For cross-origin APIs, set credentials.cors=true and make sure the server allows credentialed requests. For same-origin BFF routes, leave cors unset.

Development

Getting Started

Want to contribute or run the project locally? Here's what you need:

Requirements:

  • Node.js 22 or higher
  • npm or your favorite package manager

Setup:

# Install dependencies
npm install

# (Optional) configure example server secrets
cp examples/.env.example examples/.env.local

# Run the example dev server (loads `examples/.env` automatically)
npm run dev:examples

# Run tests
npm test

# Run tests in watch mode (great for development)
npm run test:watch

# Build the library
npm run build

External IDP toggle

The credential form in examples/ includes a "Use External IDP" checkbox powered by the IDP_LOGIN_URL, IDP_MFA_URL, and IDP_USERINFO_URL variables. Point those URLs at any identity provider that exposes compatible JSON endpoints—Grasp DP, Keycloak, Auth0, etc.—and the example app will proxy email/password + MFA requests through your backend instead of the mock database. When the toggle is off, everything runs against the mocked routes so you can develop without touching real infrastructure.

Cookie mode toggle

The example app also includes a "Use HTTP-only cookie mode" checkbox. When enabled, the example server sets HTTP-only cookies instead of returning tokens to React. Reloading the page demonstrates the cookie-session bootstrap: AuthProvider calls the configured userInfoUrl, receives the current user from the backend, and marks the session as authenticated without exposing tokens in browser storage.

The build output goes into the dist/ folder, which is what gets published to npm.

Running Tests

We use Vitest for testing because it's fast and works great with TypeScript:

npm test              # Run all tests once
npm run test:watch    # Watch mode - tests run as you make changes
npm run test:coverage # Generate a coverage report

Coverage reports are generated as HTML in the coverage/ directory.

Code Quality

Before submitting a PR, make sure your code passes linting and formatting:

npm run lint          # Check for issues
npm run lint:fix      # Auto-fix what we can
npm run format        # Format all files with Prettier

Local Beta Release

To generate and publish a beta release locally:

npm run build
npm version prerelease --preid=beta
npm publish --tag beta