Dev Tools

Keycloakify Shadcn Starter

A modern, production-ready Keycloak login theme built with React, TypeScript, Tailwind CSS v4, shadcn/ui, and Keycloakify v11. Published as an npm package with 35+ fully customized pages.

ReactTypeScriptKeycloakifyTailwind CSSshadcn/uiStorybook
https://oussemasahbeni.github.io/keycloakify-shadcn-starter
Keycloakify Shadcn Starter screenshot 1
Keycloakify Shadcn Starter screenshot 2
Keycloakify Shadcn Starter screenshot 3
Keycloakify Shadcn Starter screenshot 4
Keycloakify Shadcn Starter screenshot 5
Keycloakify Shadcn Starter screenshot 6
Slide 1 of 0 is displayed

Overview

Keycloak is a powerful open-source Identity and Access Management solution — but its default FreeMarker-based theming system is clunky and hard to maintain. This project replaces those legacy templates with a fully modern React + Tailwind CSS v4 stack using the Keycloakify v11 library, which acts as a bridge between React components and Keycloak's theming engine.

The result is a pixel-perfect, responsive login/registration flow that feels like a native part of any modern web application — and it's available as a ready-to-use npm package.

npm: @oussemasahbeni/keycloakify-login-shadcn

Key Features

  • 35+ Keycloak pages — Every login flow page is a clean React component with full TypeScript safety.
  • Dark / Light / System mode — Persistent theme toggle that respects the user's OS preference.
  • Tailwind CSS v4 + shadcn/ui — Consistent, accessible component library for a polished look.
  • Multi-language & RTL support — i18n ready with English, French, and Arabic translations.
  • Custom email templates — Branded transactional emails (verification, password reset, TOTP, etc.) built with jsx-email.
  • 16+ social login providers — Pre-styled icons for Google, GitHub, Microsoft, and more.
  • Storybook integration — UI components are developed and previewed in isolation before being wired into Keycloak.
  • Zero-config deployment — Exported as a standard .jar file that drops into any Keycloak instance.
  • Vite powered — Fast development with HMR and optimized builds.

Technical Deep Dive

Keycloakify Bridge

Keycloakify intercepts Keycloak's FreeMarker template resolution and routes page renders to React components. Each page is mapped 1-to-1:

// src/login/pages/Login.tsx
import { KcPage, KcContext } from 'keycloakify/login';

export function Login({ kcContext }: { kcContext: KcContext.Login }) {
  return (
    <div className="min-h-screen flex items-center justify-center bg-background">
      <LoginForm realm={kcContext.realm} url={kcContext.url} />
    </div>
  );
}

Component Architecture

src/
├── login/
│   ├── assets/
│   │   ├── img/          # Logo and images
│   │   └── fonts/        # Custom fonts
│   ├── pages/            # One component per Keycloak page (35+)
│   ├── components/       # Shared UI (Input, Button, Logo)
│   ├── i18n.ts           # Translations (EN, FR, AR)
│   └── index.css         # CSS variables & Tailwind config
├── components/
│   └── ui/               # shadcn/ui components
└── email/
    ├── templates/         # jsx-email template components
    └── locales/           # Email translation files

Build & Packaging

The project compiles to a Keycloak-compatible .jar archive via Keycloakify's build pipeline, making deployment as simple as dropping a file into Keycloak's providers/ directory.

Supported Pages

Authentication Account Management Security
Login Register WebAuthn Authenticate
Login with Username Update Profile WebAuthn Register
Login with Password Update Email Configure TOTP
Login OTP Delete Account Recovery Codes
Login with Passkeys Logout Confirm Reset OTP
OAuth Grant Terms & Conditions X509 Info
Device Verification Select Organization Delete Credential

Email Templates

Custom email templates are built with jsx-email and support multiple languages.

Template Description
email-verification.tsx Email verification
password-reset.tsx Password reset link
executeActions.tsx Required actions
identity-provider-link.tsx IDP linking
org-invite.tsx Organization invitation
event-login_error.tsx Login error notification
event-update_password.tsx Password change notification
event-update_totp.tsx TOTP configuration notification

Quick Start (npm)

Use the published package in any Vite + React + TypeScript project:

# 1. Create a new Vite project
pnpm create vite keycloak-theme --template react-ts
cd keycloak-theme

# 2. Install dependencies
pnpm add keycloakify @oussemasahbeni/keycloakify-login-shadcn
pnpm install

# 3. Initialize Keycloakify (select "login" + "Yes" for Stories)
npx keycloakify init

# 4. Run Storybook for visual testing
pnpm storybook

# 5. Build the Keycloak theme JAR
pnpm build-keycloak-theme

Challenges & Solutions

Challenge: Stale page re-renders during Keycloak form submission

Keycloak uses traditional HTML form POST, so React state is wiped on each round-trip.

Solution: Form state is preserved via Keycloak's built-in formData context, and validation errors are mapped from the messagesPerField API back into the React components.

Challenge: Matching Keycloak's security model for CSRF

Keycloakify automatically injects the authenticationSession token into every form, ensuring CSRF protection is never bypassed despite the React re-render.

Challenge: RTL layout for Arabic

Tailwind CSS v4 handles directional utilities natively, but component-level overrides were needed for form inputs and icon positioning.

Solution: The dir attribute is set dynamically on the root element based on the active locale, and Tailwind's rtl: variant handles layout mirroring at the component level.

Results

  • 📦 Published npm package — 669+ weekly downloads on npm
  • 80% faster theming iteration compared to raw FreeMarker development
  • 🌍 3 languages supported out of the box (EN, FR, AR with RTL)
  • 🎨 100% brand-consistent login pages across all applications in the ecosystem
  • WCAG AA compliant — fully keyboard navigable with proper ARIA labels