Wocha Docs

Choosing Components

When to use headless SDK components vs the styled UI library

Wocha offers two component layers that work together. Choose based on your needs:

Quick Decision

NeedUsePackage
Fast start, no custom designStyled components@wocha/ui
Custom design, full controlHeadless components@wocha/react or @wocha/nextjs
Styled with customisationStyled + appearance API@wocha/ui with WochaThemeProvider

Headless Components (@wocha/react)

The React SDK includes headless components that handle auth logic without any styling. They render nothing visible by default — you provide all the UI:

  • SignIn / SignUp — render props with auth state and handlers
  • Authenticated / Unauthenticated — conditional rendering wrappers
  • Protect — permission-gated rendering
  • OrgSwitcher — org selection logic

Use these when you want complete design control and already have a design system.

Styled Components (@wocha/ui)

The UI package provides ready-to-use, themed components built on top of the headless layer:

  • SignIn / SignUp — complete forms with social login, email/password, passkeys
  • UserButton — avatar dropdown with profile, org switching, sign out
  • OrgSwitcher — styled organisation selector
  • UserProfile / UserPortal — account management pages
  • AuthCard — branded container for auth flows

Theming

Customise via WochaThemeProvider:

import { WochaThemeProvider, SignIn } from '@wocha/ui';
 
<WochaThemeProvider appearance={{ theme: 'dark', radius: 'lg' }}>
  <SignIn />
</WochaThemeProvider>

Use the Theme Editor to preview and generate theme configuration.

Next.js Client Components

@wocha/nextjs/client exports the same headless components as @wocha/react, plus Next.js-specific hooks. If you are using Next.js, import from @wocha/nextjs/client rather than installing @wocha/react separately.

Combining Layers

You can mix headless and styled components in the same app:

import { Protect } from '@wocha/react';
import { UserButton } from '@wocha/ui';
 
function Header() {
  return (
    <nav>
      <Protect permission="admin:read" fallback={null}>
        <AdminLink />
      </Protect>
      <UserButton />
    </nav>
  );
}

On this page