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

@mdxui/auth

v1.5.2

Published

Authentication components and WorkOS AuthKit wrappers for mdxui

Downloads

926

Readme

@mdxui/auth

Authentication components and WorkOS AuthKit wrappers for mdxui applications. Provides a complete authentication solution with type-safe Zod schemas that extend mdxui's type system.

Installation

pnpm add @mdxui/auth

Quick Start

Zero-Config AuthApp (Recommended)

The easiest way to get started - just set environment variables:

# .env
VITE_WORKOS_CLIENT_ID=client_xxx
VITE_APP_NAME=My App
import { AuthApp } from '@mdxui/auth/shell'

function App() {
  return <AuthApp />
}

That's it! You get a complete authenticated app with:

  • Sidebar navigation with org switcher
  • Profile, Security, Sessions, API Keys, Team, and Integrations pages
  • Error boundaries with friendly messages
  • Theme support

With Explicit Config

import { AuthApp } from '@mdxui/auth/shell'

function App() {
  return (
    <AuthApp
      config={{
        branding: { name: 'My App' },
        identity: {
          clientId: 'client_xxx',
          redirectUri: 'https://myapp.com/callback',
        },
      }}
    />
  )
}

Custom Routes

import { AuthApp, accountRoutes, developerRoutes } from '@mdxui/auth/shell'
import { FileText } from 'lucide-react'
import { DocsPage } from './pages/DocsPage'

function App() {
  return (
    <AuthApp
      config={{
        branding: { name: 'My App' },
        identity: { clientId: 'client_xxx' },
        routes: [
          ...accountRoutes,      // Profile, Security, Sessions
          ...developerRoutes,    // API Keys
          {
            key: 'docs',
            path: '/docs',
            label: 'Documentation',
            icon: FileText,
            component: DocsPage,
            group: 'developer',
          },
        ],
      }}
    />
  )
}

Prebuilt Static App (Cloudflare Workers / Static Hosting)

For deployments where you don't want a build step, use the prebuilt app. The package includes a complete SPA in the app/ directory with all CSS (Tailwind), React, and routing bundled.

Option A: Serve with Hono (Recommended)

Use Hono to serve the prebuilt app with config injection from environment variables:

wrangler.toml:

name = "my-auth-app"
main = "src/index.ts"

[assets]
directory = "node_modules/@mdxui/auth/app"

[vars]
WORKOS_CLIENT_ID = "client_01EXAMPLE"
APP_NAME = "My App"

src/index.ts:

import { Hono } from 'hono'

type Bindings = {
  ASSETS: Fetcher
  WORKOS_CLIENT_ID: string
  APP_NAME?: string
  APP_TAGLINE?: string
  LOGO_URL?: string
}

const app = new Hono<{ Bindings: Bindings }>()

// Serve config from environment variables
app.get('/auth-config.json', (c) => {
  return c.json({
    clientId: c.env.WORKOS_CLIENT_ID,
    appName: c.env.APP_NAME ?? 'App',
    tagline: c.env.APP_TAGLINE,
    logoUrl: c.env.LOGO_URL,
  })
})

// Serve static assets (SPA fallback handled by assets)
app.all('*', async (c) => {
  return c.env.ASSETS.fetch(c.req.raw)
})

export default app

Option B: Vanilla Worker

If you're not using Hono, use the standard Worker API:

src/index.ts:

export interface Env {
  ASSETS: Fetcher
  WORKOS_CLIENT_ID: string
  APP_NAME?: string
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)

    // Serve config from environment variables
    if (url.pathname === '/auth-config.json') {
      return Response.json({
        clientId: env.WORKOS_CLIENT_ID,
        appName: env.APP_NAME ?? 'App',
      })
    }

    // Serve static assets
    return env.ASSETS.fetch(request)
  }
}

Both approaches:

  • No copying files needed
  • Config comes from secure environment variables
  • Easy to update by bumping the package version

Option C: Copy to Static Directory

Copy the prebuilt app and add your config file:

1. Install and copy:

pnpm add @mdxui/auth
cp -r node_modules/@mdxui/auth/app/* public/

2. Create public/auth-config.json:

{
  "clientId": "client_01EXAMPLE",
  "appName": "My App"
}

3. Configure wrangler.toml:

name = "my-auth-app"

[assets]
directory = "public"

This approach:

  • Works with any static hosting (Netlify, Vercel, S3, etc.)
  • Config is a static file in your repo
  • Requires re-copying after package updates

Config Options

| Field | Required | Description | |-------|----------|-------------| | clientId | Yes | WorkOS client ID | | appName | No | App name (default: "App") | | tagline | No | Subtitle shown in sidebar | | redirectUri | No | OAuth redirect URI | | apiHostname | No | WorkOS API hostname | | devMode | No | Enable dev mode (default: false) | | logoUrl | No | URL to logo image |

Traditional Setup (Without Shell)

import {
  IdentityProvider,
  AuthGate,
  useAuth,
  UserProfile,
} from '@mdxui/auth'

function App() {
  return (
    <IdentityProvider clientId="client_xxx">
      <AuthGate>
        <Dashboard />
      </AuthGate>
    </IdentityProvider>
  )
}

function Dashboard() {
  const { user, getAccessToken } = useAuth()

  return (
    <div>
      <h1>Welcome, {user?.firstName}!</h1>
      <UserProfile authToken={getAccessToken} />
    </div>
  )
}

Features

  • Zero-Config AuthApp - Complete authenticated app shell with environment variable support
  • Pre-built Pages - Profile, Security, Sessions, API Keys, Team, and Integrations pages
  • Route Presets - Composable route groups (accountRoutes, developerRoutes, adminRoutes)
  • SidebarOrgSwitcher - Auto-wired org switcher with branding fallback
  • WidgetErrorBoundary - Friendly, contextual error messages for widget failures
  • Authentication Providers - IdentityProvider and AuthGate for managing auth state
  • WorkOS Widgets - Pre-built components for user management (profile, security, API keys)
  • Vault Components - UI for managing encrypted secrets with VaultProvider
  • Secrets Manager - Full-featured secrets management widget
  • Type-Safe Schemas - Zod schemas extending mdxui's UserIdentity and Session types
  • React Hooks - useAuth, useWidgetToken, and useVault for accessing state
  • UI Components - Sign in/out buttons, user menu, team switcher

Exports

Main Entry (@mdxui/auth)

Everything you need for most use cases:

import {
  // Providers
  IdentityProvider,
  IdentityProviderMinimal,
  AuthGate,
  WidgetsProvider,
  VaultProvider,

  // Widgets
  UserProfile,
  UserSecurity,
  UserSessions,
  ApiKeys,
  UsersManagement,
  OrganizationSwitcher,

  // Vault Components
  VaultList,
  VaultItemCard,
  VaultInputModal,
  VaultDeleteDialog,
  VaultEmptyState,
  SecretsManager,

  // Components
  SignInButton,
  SignOutButton,
  UserMenu,
  TeamSwitcher,

  // Hooks
  useAuth,
  useWidgetToken,
  useVault,
  useVaultContext,

  // Schemas
  AuthUserSchema,
  AuthSessionSchema,
  AuthOrganizationSchema,
} from '@mdxui/auth'

// Types
import type {
  AuthUser,
  AuthSession,
  AuthOrganization,
  AuthToken,
  VaultClient,
  VaultItem,
  VaultField,
} from '@mdxui/auth'

Shell Exports (@mdxui/auth/shell)

Complete authenticated app shell with routing:

import {
  // App Components
  AuthApp,              // Zero-config app with built-in routing
  AuthAppWithChildren,  // App shell without routing (bring your own)
  AuthAppProvider,      // Providers only (for custom layouts)
  AuthShell,            // Shell layout component
  AuthShellNav,         // Navigation component

  // Shell Components
  SidebarOrgSwitcher,   // Org switcher with branding fallback
  WidgetErrorBoundary,  // Error boundary with friendly messages
  Breadcrumbs,          // Breadcrumb navigation

  // Pre-built Pages
  ProfilePage,          // User profile management
  SecurityPage,         // Password and MFA settings
  SessionsPage,         // Active sessions management
  ApiKeysPage,          // API key management
  TeamPage,             // Team member management (requires org)
  IntegrationsPage,     // Third-party integrations

  // Route Presets
  defaultRoutes,        // All default routes
  defaultGroups,        // Default route groups
  accountRoutes,        // Profile, Security, Sessions
  developerRoutes,      // API Keys
  adminRoutes,          // Team management
  integrationRoutes,    // Integrations

  // Config Hooks
  useAuthShellConfig,
  useAuthShellRoutes,
  useAuthShellBranding,
} from '@mdxui/auth/shell'

// Types
import type {
  AuthAppConfig,
  AuthAppProps,
  AuthAppRoute,
  AuthShellBranding,
  AuthShellIdentity,
} from '@mdxui/auth/shell'

Subpath Exports

For more granular imports:

// Only providers
import { IdentityProvider, AuthGate } from '@mdxui/auth/providers'

// Only widgets
import { UserProfile, ApiKeys } from '@mdxui/auth/widgets'

// Only components
import { SignInButton, UserMenu } from '@mdxui/auth/components'

// Only hooks
import { useAuth, useWidgetToken } from '@mdxui/auth/hooks'

// Only schemas (for runtime validation)
import { AuthUserSchema, AuthSessionSchema } from '@mdxui/auth/schemas'

// Only types
import type { AuthUser, AuthGateProps } from '@mdxui/auth/types'

Type System

AuthUser extends UserIdentity

AuthUser extends mdxui's UserIdentity with WorkOS-specific fields:

import type { UserIdentity } from 'mdxui/admin'
import type { AuthUser } from '@mdxui/auth'

// AuthUser includes all UserIdentity fields plus WorkOS extras
const user: AuthUser = {
  // From UserIdentity
  id: 'user_123',
  email: '[email protected]',
  firstName: 'John',
  lastName: 'Doe',
  roles: ['admin'],
  permissions: ['users:read', 'users:write'],
  organizationId: 'org_123',

  // WorkOS-specific
  emailVerified: true,
  createdAt: '2024-01-01T00:00:00Z',
  updatedAt: '2024-01-15T00:00:00Z',
}

// AuthUser is assignable to UserIdentity
const identity: UserIdentity = user // Works!

Runtime Validation with Zod

Use schemas for validating API responses:

import { AuthUserSchema, AuthSessionSchema } from '@mdxui/auth/schemas'

// Validate user data
const result = AuthUserSchema.safeParse(apiResponse)
if (result.success) {
  console.log('Valid user:', result.data.email)
} else {
  console.error('Invalid user:', result.error)
}

// Session with impersonation support
const sessionResult = AuthSessionSchema.safeParse({
  id: 'session_123',
  userId: 'user_123',
  createdAt: '2024-01-01T00:00:00Z',
  expiresAt: '2024-01-02T00:00:00Z',
  impersonator: {
    email: '[email protected]',
    reason: 'Customer support',
  },
})

AuthApp (Shell)

Zero-Config with Environment Variables

AuthApp can read configuration from environment variables, perfect for Cloudflare Workers Static Assets:

# .env
VITE_WORKOS_CLIENT_ID=client_xxx        # Required
VITE_WORKOS_REDIRECT_URI=https://...    # Optional
VITE_WORKOS_API_HOSTNAME=auth.apis.do   # Optional
VITE_WORKOS_DEV_MODE=true               # Optional
VITE_APP_NAME=My App                    # Optional (defaults to "App")
VITE_APP_TAGLINE=Best app ever          # Optional
import { AuthApp } from '@mdxui/auth/shell'

// That's it - reads config from env vars
function App() {
  return <AuthApp />
}

Route Presets

Compose routes from presets:

import {
  AuthApp,
  accountRoutes,      // Profile, Security, Sessions
  developerRoutes,    // API Keys
  adminRoutes,        // Team
  integrationRoutes,  // Integrations
  defaultGroups,
} from '@mdxui/auth/shell'

function App() {
  return (
    <AuthApp
      config={{
        branding: { name: 'My App' },
        identity: { clientId: 'client_xxx' },
        groups: defaultGroups,
        routes: [
          ...accountRoutes,
          ...developerRoutes,
          // Exclude adminRoutes if you don't need team management
        ],
      }}
    />
  )
}

WidgetErrorBoundary

Wraps WorkOS widgets with friendly error handling:

import { WidgetErrorBoundary } from '@mdxui/auth/shell'
import { UserProfile } from '@mdxui/auth/widgets'

function ProfilePage() {
  return (
    <WidgetErrorBoundary widgetName="profile">
      <UserProfile authToken={getAccessToken} />
    </WidgetErrorBoundary>
  )
}
// On error: "Your profile is camera shy right now..."
// Unknown widgets: "Something went wrong loading your API Keys..."

Custom Sidebar Header

import { AuthApp, SidebarOrgSwitcher } from '@mdxui/auth/shell'

// Default: SidebarOrgSwitcher is included automatically
<AuthApp config={config} />

// Custom header content
<AuthApp
  config={config}
  sidebarHeaderContent={<MyCustomHeader />}
/>

Components

IdentityProvider

Wraps your app with authentication context:

<IdentityProvider
  clientId="client_xxx"
  devMode={process.env.NODE_ENV === 'development'}
  redirectUri="http://localhost:3000/callback"
>
  <App />
</IdentityProvider>

AuthGate

Protects routes requiring authentication:

// Redirect unauthenticated users
<AuthGate onUnauthenticated="redirect" redirectUrl="/login">
  <ProtectedContent />
</AuthGate>

// Show landing page for unauthenticated users
<AuthGate
  onUnauthenticated="landing"
  landingComponent={<LandingPage />}
  loadingComponent={<LoadingSpinner />}
>
  <Dashboard />
</AuthGate>

// Allow access but with different content
<AuthGate onUnauthenticated="allow">
  {({ user }) => user ? <Dashboard /> : <PublicView />}
</AuthGate>

Widgets

Pre-built WorkOS widgets for user management:

function SettingsPage() {
  const { getAccessToken } = useAuth()

  return (
    <WidgetsProvider appearance="dark">
      <Tabs>
        <TabPanel label="Profile">
          <UserProfile authToken={getAccessToken} />
        </TabPanel>
        <TabPanel label="Security">
          <UserSecurity authToken={getAccessToken} />
        </TabPanel>
        <TabPanel label="Sessions">
          <UserSessions authToken={getAccessToken} />
        </TabPanel>
        <TabPanel label="API Keys">
          <ApiKeys authToken={getAccessToken} />
        </TabPanel>
      </Tabs>
    </WidgetsProvider>
  )
}

Hooks

useAuth

Access authentication state and methods:

function ProfileButton() {
  const {
    user,           // Current user or null
    isLoading,      // Loading state
    isAuthenticated,// Boolean auth status
    signIn,         // Sign in method
    signOut,        // Sign out method
    getAccessToken, // Get access token for API calls
  } = useAuth()

  if (isLoading) return <Spinner />
  if (!isAuthenticated) return <SignInButton />

  return <UserMenu user={user} onSignOut={signOut} />
}

useWidgetToken

Fetch tokens for WorkOS widgets:

function ApiKeysWidget() {
  const { token, loading, error, refetch } = useWidgetToken({
    widget: 'api-keys',
    organizationId: 'org_123',
    endpoint: '/api/workos/widget-token', // default
  })

  if (loading) return <Spinner />
  if (error) return <Error message={error} onRetry={refetch} />

  return <ApiKeys authToken={token} />
}

Vault Components

@mdxui/auth includes components for managing encrypted secrets via WorkOS Vault.

VaultProvider

Wrap your app with VaultProvider to enable vault functionality:

import { VaultProvider, useVault } from '@mdxui/auth'

function App() {
  const vaultClient = useMyVaultClient() // Your vault client implementation

  return (
    <VaultProvider client={vaultClient}>
      <SecretsPage />
    </VaultProvider>
  )
}

useVault Hook

Access vault state and operations:

function SecretsPage() {
  const {
    items,        // Array of vault items
    isLoading,    // Loading state
    error,        // Error message if any
    createItem,   // Create new secret
    updateItem,   // Update existing secret
    deleteItem,   // Delete a secret
    refresh,      // Refresh the list
  } = useVault()

  return <VaultList items={items} onRefresh={refresh} />
}

Vault UI Components

Pre-built components for secrets management:

import {
  VaultList,
  VaultItemCard,
  VaultInputModal,
  VaultDeleteDialog,
  VaultEmptyState,
} from '@mdxui/auth'

function SecretsManager() {
  const { items, isLoading, createItem, deleteItem } = useVault()
  const [showCreate, setShowCreate] = useState(false)
  const [deleteTarget, setDeleteTarget] = useState(null)

  if (isLoading) return <Spinner />
  if (items.length === 0) return <VaultEmptyState onCreate={() => setShowCreate(true)} />

  return (
    <>
      <VaultList
        items={items}
        onItemClick={(item) => console.log('View', item)}
        onItemDelete={(item) => setDeleteTarget(item)}
      />

      <VaultInputModal
        open={showCreate}
        onClose={() => setShowCreate(false)}
        onSubmit={async (data) => {
          await createItem(data)
          setShowCreate(false)
        }}
      />

      <VaultDeleteDialog
        open={!!deleteTarget}
        item={deleteTarget}
        onClose={() => setDeleteTarget(null)}
        onConfirm={async () => {
          await deleteItem(deleteTarget.id)
          setDeleteTarget(null)
        }}
      />
    </>
  )
}

SecretsManager Widget

A complete, ready-to-use secrets management interface:

import { SecretsManager } from '@mdxui/auth'

function SettingsPage() {
  return (
    <SecretsManager
      context={{ organizationId: 'org_123' }}
      onSecretChange={(secret) => console.log('Changed:', secret)}
    />
  )
}

API Reference

Schemas

| Schema | Extends | Description | |--------|---------|-------------| | AuthUserSchema | UserIdentitySchema | User with WorkOS fields | | AuthSessionSchema | SessionSchema | Session with impersonation | | AuthOrganizationSchema | - | WorkOS organization | | ImpersonatorSchema | - | Admin impersonation info | | AuthGatePropsSchema | - | AuthGate component props | | WidgetsProviderPropsSchema | - | WidgetsProvider props |

Types

| Type | Description | |------|-------------| | AuthUser | Inferred from AuthUserSchema | | AuthSession | Inferred from AuthSessionSchema | | AuthOrganization | WorkOS organization | | AuthToken | string \| (() => Promise<string>) | | Impersonator | Admin performing impersonation |

License

MIT