Skip to main content
@kavachos/ui provides drop-in React components for auth flows. Each component renders inside KavachProvider from @kavachos/react and wires up to your KavachOS API route automatically, no manual fetch calls required.
Components require @kavachos/react to be installed and a KavachProvider wrapping your app. See the React hooks page for provider setup.

Installation

pnpm add @kavachos/ui
Components are unstyled by default and rely on Tailwind CSS for layout and spacing. Add @kavachos/ui to your tailwind.config.ts content paths:
// tailwind.config.ts
export default {
  content: [
    './src/**/*.{ts,tsx}',
    './node_modules/@kavachos/ui/src/**/*.{ts,tsx}',
  ],
};

Available components

ComponentDescription
SignInEmail/password and magic-link sign-in form
SignUpNew account registration form
UserButtonAvatar dropdown with sign-out and custom menu items
ForgotPasswordPassword reset request form
TwoFactorVerifyTOTP/backup-code entry for 2FA flows
OAuthButtonsSocial login buttons (Google, GitHub, Discord, and more)
AuthCardGeneric card shell for building custom auth pages

SignIn

Renders an email/password form. Pass showMagicLink to add a passwordless tab. Pass providers to show OAuth buttons above the form.
import { SignIn } from '@kavachos/ui';
import { OAUTH_PROVIDERS } from '@kavachos/ui';

export default function LoginPage() {
  return (
    <SignIn
      providers={[OAUTH_PROVIDERS.google, OAUTH_PROVIDERS.github]}
      showMagicLink
      signUpUrl="/sign-up"
      forgotPasswordUrl="/forgot-password"
      onSuccess={() => window.location.href = '/dashboard'}
    />
  );
}
providers
OAuthProviderMeta[]
default:"[]"
OAuth providers to show above the form.
Add a magic-link tab alongside password sign-in.
signUpUrl
string
URL for the “Sign up” link in the footer.
forgotPasswordUrl
string
URL for the “Forgot password?” link.
onSuccess
() => void
Called on successful sign-in.
title
string
default:"\"Sign in\""
Heading text.
basePath
string
default:"\"/api/kavach\""
Must match your KavachOS API route.

SignUp

import { SignUp } from '@kavachos/ui';

export default function RegisterPage() {
  return (
    <SignUp
      showName
      confirmPassword
      signInUrl="/sign-in"
      onSuccess={() => window.location.href = '/dashboard'}
    />
  );
}
showName
boolean
default:"false"
Include a name field.
confirmPassword
boolean
default:"false"
Add a confirm-password field.
signInUrl
string
URL for the “Sign in” link.
onSuccess
() => void
Called on successful registration.

UserButton

Renders an avatar that opens a dropdown menu. Includes sign-out by default. Pass menuItems to add custom actions.
import { UserButton } from '@kavachos/ui';

export default function Nav() {
  return (
    <UserButton
      showEmail
      menuItems={[
        { label: 'Settings', onClick: () => router.push('/settings') },
        { label: 'Delete account', onClick: handleDelete, danger: true },
      ]}
      onSignOut={() => router.push('/sign-in')}
    />
  );
}

OAuthButtons

Use standalone when you want social login without the full sign-in card.
import { OAuthButtons, OAUTH_PROVIDERS } from '@kavachos/ui';

<OAuthButtons
  providers={[
    OAUTH_PROVIDERS.google,
    OAUTH_PROVIDERS.github,
    OAUTH_PROVIDERS.discord,
  ]}
  mode="signin"
  layout="list"
/>
OAUTH_PROVIDERS ships with metadata and icons for Google, GitHub, GitLab, Discord, Twitter, Facebook, Microsoft, Apple, LinkedIn, Slack, Notion, Reddit, Spotify, and Twitch. You can also pass a custom provider object matching OAuthProviderMeta.

Customization

Class name overrides

Every component accepts a classNames prop with keys for each sub-element. Pass a string to append classes, or a function that receives the default class string.
<SignIn
  classNames={{
    card: 'shadow-none border-0',
    button: (defaults) => `${defaults} bg-violet-600 hover:bg-violet-500`,
    input: 'rounded-none border-b border-zinc-300',
  }}
/>

Slot replacement

Pass a components prop to replace any primitive (input, button, link, divider, error). Useful when you need to use your own design system components.
import { SignIn } from '@kavachos/ui';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';

<SignIn
  components={{
    Button: ({ children, loading, ...props }) => (
      <Button {...props} disabled={loading}>{children}</Button>
    ),
    Input: ({ label, error, ...props }) => (
      <div>
        <label>{label}</label>
        <Input {...props} />
        {error && <p className="text-red-500 text-xs">{error}</p>}
      </div>
    ),
  }}
/>
The cx utility is exported from @kavachos/ui for merging class names in your own slot components.

Framework examples

Next.js App Router

// app/(auth)/sign-in/page.tsx
import { SignIn } from '@kavachos/ui';

export default function SignInPage() {
  return (
    <main className="flex min-h-screen items-center justify-center">
      <SignIn
        signUpUrl="/sign-up"
        forgotPasswordUrl="/forgot-password"
        onSuccess={() => {
          // Client navigation — wrap in 'use client' if needed
          window.location.href = '/dashboard';
        }}
      />
    </main>
  );
}

Vite + React Router

// src/pages/sign-in.tsx
import { useNavigate } from 'react-router-dom';
import { SignIn } from '@kavachos/ui';

export function SignInPage() {
  const navigate = useNavigate();

  return (
    <div className="flex min-h-screen items-center justify-center">
      <SignIn
        signUpUrl="/sign-up"
        onSuccess={() => navigate('/dashboard')}
      />
    </div>
  );
}

Next steps

React hooks

useSession, useUser, useSignIn, and more.

Adapters

Mount the KavachOS handler in Next.js, Express, Hono, and others.

Auth

Configure email/password, magic links, OAuth, and 2FA.