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

@blacksmith-ui/auth

v0.1.7

Published

Configurable authentication UI components built on @blacksmith-ui/react — supports standard and third-party auth providers

Readme

@blacksmith-ui/auth

Drop-in authentication UI components for React — login, registration, password reset, and social login with a pluggable adapter pattern. Built on @blacksmith-ui/react and @blacksmith-ui/forms.

Part of the blacksmith-cli ecosystem. This library powers the default auth flows for blacksmith-cli scaffolded projects, but is fully standalone and can be used in any React application.

npm version license storybook

Features

  • 4 auth flows — Login, register, forgot password, and reset password forms
  • Social login — Google, GitHub, Facebook, Apple, Microsoft, and Twitter OAuth buttons
  • Adapter pattern — Works with any auth backend (Firebase, Supabase, Auth0, custom APIs)
  • Built-in adapters — Mock adapter for development, Firebase adapter for production
  • Full i18n support — Every label is customizable via the labels prop
  • Zod validation — Client-side form validation with clear error messages
  • AuthProvider context — Manages auth state and provides useAuth() hook
  • Accessible — Keyboard navigable, proper ARIA attributes, screen reader friendly

Installation

npm install @blacksmith-ui/auth @blacksmith-ui/react
# or
yarn add @blacksmith-ui/auth @blacksmith-ui/react

Peer Dependencies

npm install react react-dom tailwindcss lucide-react

| Peer Dependency | Version | |-----------------|---------| | @blacksmith-ui/react | ^0.1.0 | | react | ^18.0.0 \|\| ^19.0.0 | | react-dom | ^18.0.0 \|\| ^19.0.0 | | tailwindcss | ^3.3.0 |

Note: @blacksmith-ui/forms is a direct dependency and installed automatically.

Tailwind Configuration

Add all three packages to your Tailwind content array:

// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{ts,tsx}',
    './node_modules/@blacksmith-ui/react/dist/**/*.{js,mjs}',
    './node_modules/@blacksmith-ui/forms/dist/**/*.{js,mjs}',
    './node_modules/@blacksmith-ui/auth/dist/**/*.{js,mjs}',
  ],
  // ... theme config from @blacksmith-ui/react setup
};

Quick Start

import { AuthProvider, LoginForm, createMockAdapter } from '@blacksmith-ui/auth';
import '@blacksmith-ui/react/styles.css';

const adapter = createMockAdapter();

function App() {
  return (
    <AuthProvider adapter={adapter}>
      <LoginForm
        onSuccess={(user) => console.log('Logged in:', user)}
        socialProviders={['google', 'github']}
      />
    </AuthProvider>
  );
}

Components

LoginForm

Email/password login with optional social providers and "remember me" checkbox.

<LoginForm
  onSuccess={(user) => navigate('/dashboard')}
  error={error}                         // External error to display
  loading={isLoading}                   // Disables form, shows loading state
  socialProviders={['google', 'github']}
  onForgotPassword={() => navigate('/forgot-password')}
  onRegister={() => navigate('/register')}
  labels={{ loginTitle: 'Welcome back' }}
  className="max-w-md"
/>

RegisterForm

User registration with name, email, password, and password confirmation.

<RegisterForm
  onSuccess={(user) => navigate('/verify-email')}
  error={error}
  loading={isLoading}
  socialProviders={['google', 'github']}
  onLogin={() => navigate('/login')}
  labels={{ registerTitle: 'Get started' }}
/>

ForgotPasswordForm

Password recovery — sends a reset email to the user.

<ForgotPasswordForm
  onSuccess={() => showToast('Check your email')}
  error={error}
  loading={isLoading}
  onLogin={() => navigate('/login')}
/>

ResetPasswordForm

Set a new password using a reset token/code.

<ResetPasswordForm
  code={resetToken}  // From URL params
  onSuccess={() => navigate('/login')}
  error={error}
  loading={isLoading}
/>

SocialLoginButtons

Standalone social login buttons that can be used independently.

<SocialLoginButtons
  providers={['google', 'github', 'apple']}
  onSocialLogin={(provider) => handleSocial(provider)}
  loading={isLoading}
/>

AuthLayout

Card wrapper for auth forms with title, description, and footer slot.

<AuthLayout
  title="Welcome back"
  description="Sign in to your account"
  footer={<p>Need help? <a href="/support">Contact support</a></p>}
>
  {/* Form content */}
</AuthLayout>

Common Props

All form components share these props:

| Prop | Type | Description | |------|------|-------------| | onSuccess | (user: AuthUser) => void | Called after successful authentication | | error | AuthError \| null | External error to display (e.g., from API) | | loading | boolean | Disables inputs and shows loading state on submit button | | labels | Partial<AuthLabels> | Override any text label for i18n | | className | string | Additional CSS classes |

Auth Adapters

The adapter pattern decouples the UI from the auth implementation. Implement the AuthAdapter interface to connect any backend:

interface AuthAdapter {
  signInWithEmail(email: string, password: string): Promise<AuthResult>;
  signUpWithEmail(email: string, password: string, displayName?: string): Promise<AuthResult>;
  signInWithSocial(provider: SocialProvider): Promise<AuthResult>;
  sendPasswordResetEmail(email: string): Promise<{ success: boolean; error?: AuthError }>;
  confirmPasswordReset(code: string, newPassword: string): Promise<{ success: boolean; error?: AuthError }>;
  signOut(): Promise<void>;
  getCurrentUser(): AuthUser | null;
  onAuthStateChanged(callback: (user: AuthUser | null) => void): () => void;
}

Mock Adapter

For development and testing:

import { createMockAdapter } from '@blacksmith-ui/auth';

const adapter = createMockAdapter({
  simulateDelay: 1000,  // Simulate network latency (ms)
  // Pre-populated users, auto-success, etc.
});

Firebase Adapter

For Firebase Authentication:

import { createFirebaseAdapter } from '@blacksmith-ui/auth';
import { getAuth } from 'firebase/auth';

const auth = getAuth(firebaseApp);
const adapter = createFirebaseAdapter({ auth });

Custom Adapter

Connect to any backend:

const customAdapter: AuthAdapter = {
  async signInWithEmail(email, password) {
    const res = await fetch('/api/auth/login', {
      method: 'POST',
      body: JSON.stringify({ email, password }),
    });
    if (!res.ok) {
      return { success: false, error: { code: 'auth/failed', message: 'Invalid credentials' } };
    }
    const user = await res.json();
    return { success: true, user };
  },
  // ... implement remaining methods
};

AuthProvider & useAuth

AuthProvider manages auth state and exposes it via the useAuth() hook:

import { AuthProvider, useAuth } from '@blacksmith-ui/auth';

function App() {
  return (
    <AuthProvider adapter={adapter}>
      <AppContent />
    </AuthProvider>
  );
}

function AppContent() {
  const { user, loading, signOut } = useAuth();

  if (loading) return <Spinner />;
  if (!user) return <LoginForm />;

  return (
    <div>
      <p>Welcome, {user.displayName}</p>
      <button onClick={signOut}>Sign out</button>
    </div>
  );
}

Internationalization (i18n)

Every text label can be overridden via the labels prop on any form component:

<LoginForm
  labels={{
    loginTitle: 'Bienvenue',
    loginDescription: 'Connectez-vous a votre compte',
    loginButton: 'Se connecter',
    emailLabel: 'Adresse email',
    emailPlaceholder: '[email protected]',
    passwordLabel: 'Mot de passe',
    forgotPasswordLink: 'Mot de passe oublie ?',
    registerLink: "Pas de compte ? S'inscrire",
    orContinueWith: 'Ou continuer avec',
  }}
/>

Available Labels

| Label | Default | |-------|---------| | loginTitle | "Welcome back" | | loginDescription | "Sign in to your account" | | loginButton | "Sign in" | | registerTitle | "Create an account" | | registerDescription | "Get started with a new account" | | registerButton | "Create account" | | forgotPasswordTitle | "Forgot password" | | forgotPasswordButton | "Send reset link" | | resetPasswordTitle | "Reset password" | | resetPasswordButton | "Reset password" | | emailLabel | "Email" | | passwordLabel | "Password" | | confirmPasswordLabel | "Confirm password" | | displayNameLabel | "Full name" | | rememberMe | "Remember me" | | forgotPasswordLink | "Forgot password?" | | loginLink | "Already have an account? Sign in" | | registerLink | "Don't have an account? Sign up" | | orContinueWith | "Or continue with" |

Types

Key TypeScript types exported from this package:

import type {
  AuthUser,           // { id, email, displayName, photoURL, emailVerified, providerId }
  AuthAdapter,        // Interface for auth backend implementations
  AuthResult,         // { success: true, user } | { success: false, error }
  AuthError,          // { code: string, message: string }
  AuthLabels,         // All customizable text labels
  SocialProvider,     // 'google' | 'github' | 'facebook' | 'apple' | 'microsoft' | 'twitter'
  AuthConfig,         // AuthProvider configuration
  LoginFormProps,
  RegisterFormProps,
  ForgotPasswordFormProps,
  ResetPasswordFormProps,
  SocialLoginButtonsProps,
  AuthLayoutProps,
  AuthProviderProps,
  AuthContextValue,
} from '@blacksmith-ui/auth';

Development

Prerequisites

  • Node.js >= 20 (use nvm use)
  • Yarn 1.x (Classic)
  • Build upstream packages first: @blacksmith-ui/react then @blacksmith-ui/forms

Commands

# Build (build react + forms first)
yarn workspace @blacksmith-ui/auth build

# Test
yarn workspace @blacksmith-ui/auth test

# Test with coverage
yarn workspace @blacksmith-ui/auth test:coverage

# Storybook (port 6007)
yarn workspace @blacksmith-ui/auth storybook

Project Structure

src/
├── components/
│   ├── auth-layout/            # Card wrapper with title/description/footer
│   ├── login-form/             # LoginForm + tests
│   ├── register-form/          # RegisterForm + tests
│   ├── forgot-password-form/   # ForgotPasswordForm + tests
│   ├── reset-password-form/    # ResetPasswordForm + tests
│   └── social-login-buttons/   # OAuth provider buttons
├── adapters/
│   ├── mock-adapter.ts         # Mock adapter for development/testing
│   └── firebase-adapter.ts     # Firebase Authentication adapter
├── providers/
│   └── auth-provider.tsx       # AuthProvider + useAuth hook
├── types/
│   └── auth.ts                 # AuthUser, AuthAdapter, AuthLabels, etc.
├── styles/globals.css
└── index.ts

Related Packages

| Package | Description | |---------|-------------| | @blacksmith-ui/react | Core UI primitives (required peer dependency) | | @blacksmith-ui/forms | Form components with Zod validation (bundled dependency) |

License

MIT