@stackra/auth-ui
v1.5.0
Published
Batteries-included authentication UI kit — 11 forms, 5 layout variants, 12 reusable composites — built on @stackra/ui (HeroUI OSS + Pro). Sits on top of @stackra/auth's headless runtime per ADR-0037. Phase 2 of the frontend auth split.
Maintainers
Readme
@stackra/auth-ui
Batteries-included authentication UI kit — 11 forms, 5 layout shells, 10
reusable composites, and every shipped route + resolver — built on
@stackra/ui (HeroUI OSS + Pro). Sits on top of
@stackra/auth's headless runtime per
ADR-0037.
Phase 2 of the frontend auth split. Third product in the trio:
| Layer | Package | Ships |
| ------------------------ | ------------------------ | ---------------------------------------------------- |
| Permission gating (slim) | @stackra/authorization | useCan, guards, <PermissionGate> |
| Login runtime (heavy) | @stackra/auth | AuthService, 22 hooks, 8 Zod schemas |
| UI kit (this file) | @stackra/auth-ui | Layouts + forms + composites + resolver + routes |
Consumers that own their login flow can skip this package and drive the hooks in
@stackra/auth directly. Consumers that want the default screens depend on all
three.
Install
pnpm add @stackra/auth-ui @stackra/auth @stackra/authorization \
@stackra/container @stackra/contracts @stackra/decorators \
@stackra/http @stackra/routing @stackra/support @stackra/ui \
react reflect-metadata zodQuick start
import "reflect-metadata";
import { AuthModule } from "@stackra/auth";
import { WebAuthUiModule } from "@stackra/auth-ui/react";
import { AuthorizationModule } from "@stackra/authorization";
import { Module } from "@stackra/container";
@Module({
imports: [
AuthorizationModule.forRoot(),
AuthModule.forRoot({ appName: "Acme" }),
WebAuthUiModule.forRoot({ variant: "card" }),
],
})
export class AppModule {}WebAuthUiModule.forRoot(options) composes AuthUiModule.forRoot(options) and
self-registers the 11 auth routes via RoutingModule.forFeature(...). Consumers
who want to author their own routes can import AuthUiModule from the . entry
and skip the route registration.
Every screen is a route record ready to plug into your router directly:
import { buildAuthUiRoutes } from "@stackra/auth-ui/react";
export const routes = [
...buildAuthUiRoutes(),
// ...your app routes
];Or mount a page directly:
import { AuthPageResolver } from "@stackra/auth-ui/react";
function LoginPage() {
return <AuthPageResolver page="login" />;
}Public API
. — module + configuration
AuthUiModule.forRoot(options)/.forRootAsync(options)— DI module. Registers the 5 layout variants in the workspace variant registry at bootstrap.AUTH_UI_CONFIGDI token (in@stackra/contractsper the 2026-07-25 contracts-decorators promotion sweep).- Constants —
AUTH_SLOTS,AUTH_ROUTE_PATHS. - Interfaces + types for consumers who want to author their own variants
(
IAuthUiConfig,IAuthUiVariantConfig, ...).
./react — every visual component
Layouts:
<AuthLayout>(compound) +<AuthLayoutHeader>+<AuthLayoutFooter>+<AuthCard>.- Five shells —
<AuthCardShell>,<AuthEmbeddedShell>,<AuthMinimalShell>,<AuthSimpleShell>,<AuthSplitShell>.SHELL_MAPmaps variant name → shell.
Forms (11):
<LoginForm>,<RegisterForm>,<ForgotPasswordForm>,<ResetPasswordForm>,<ForcePasswordForm>,<MfaChallengeForm>,<OtpVerificationForm>,<MagicLinkForm>,<PhoneLoginForm>,<LockScreenForm>,<LogoutForm>.FORM_MAPmaps page name → form.
Composites (10):
<SocialProviders>+SOCIAL_ICONS,<PasswordInput>,<PasswordStrength>,<PasswordChecklist>,<IdentityInput>,<AmbientGlow>,<BackgroundPattern>,<FooterLinks>,<TermsNotice>,<VariantCustomizer>.
Resolver + routes:
<AuthPageResolver>— picks the active variant based on the resolver config.buildAuthUiRoutes(overrides?)— factory that returns every shipped route record. Individual route records (loginRoute,registerRoute,forgotPasswordRoute,resetPasswordRoute,forcePasswordRoute,mfaChallengeRoute,otpVerificationRoute,magicLinkRoute,phoneLoginRoute,lockScreenRoute,logoutRoute) are also exported directly.
Provider + hooks:
<AuthUiProvider>— wired automatically byWebAuthUiModule.forRoot(...).AuthUiContext+IAuthUiContextValueexposed for advanced composition.- Hooks —
useAuthUiConfig,useAuthT(translator resolver, returns anAuthUiTranslatorfunction),useSetVariantOverride.
Module:
WebAuthUiModule.forRoot(options)— react-subpath web module. ComposesAuthUiModule.forRoot(options)and self-registers the 11 shipped auth routes viaRoutingModule.forFeature(...).
./testing — render helper + assertion utility
renderAuthForm(ui, options)— mounts<AuthUiProvider>+<AuthLayout>+ shell around any form. ReturnsIRenderAuthFormResultwith the mounted RTL wrapper.expectValidationError(container, message)— asserts a visible field error contains a substring; throws with a helpful diff on mismatch.
Design brief
Full brief lives at
docs/design/auth-ui/README.md, with
route tree
(information-architecture.md),
per-screen contracts
(screen-contracts.md),
layouts (layouts.md), and composites
(components.md).
React Native (./native)
The ./native subpath ships five auth screens composed on HeroUI Native +
HeroUI Native Pro via @stackra/ui/native. Screens share the
cross-platform i18n catalogs under src/core/i18n/ — one source of truth for
web + RN.
Install
Add the RN peers alongside the base install:
pnpm add @stackra/auth-ui @stackra/auth @stackra/authorization \
@stackra/container @stackra/contracts @stackra/decorators \
@stackra/http @stackra/i18n @stackra/support @stackra/ui \
heroui-native heroui-native-pro \
react react-native react-native-safe-area-context \
reflect-metadata zodWire the module
import "reflect-metadata";
import { NativeAuthModule } from "@stackra/auth/native";
import { NativeAuthUiModule } from "@stackra/auth-ui/native";
import { NativeI18nModule } from "@stackra/i18n/native";
import { Module } from "@stackra/container";
@Module({
imports: [
NativeI18nModule.forRoot({ defaultLocale: "en" }),
NativeAuthModule.forRoot({
api: { baseURL: "https://api.example.com/v1/auth" },
biometric: true,
}),
NativeAuthUiModule.forRoot({
appName: "Acme",
socialProviders: [{ id: "google", label: "Google" }],
showBiometricCta: true,
}),
],
})
export class AppModule {}Compose screens into React Navigation
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import {
buildNativeAuthRoutes,
useAuthUiConfig,
} from "@stackra/auth-ui/native";
const Stack = createNativeStackNavigator();
export function AuthNavigator() {
const config = useAuthUiConfig();
const routes = buildNativeAuthRoutes(config);
return (
<NavigationContainer
linking={{
prefixes: ["stackra://", "https://app.stackra.com"],
config: {
screens: Object.fromEntries(routes.map((r) => [r.name, r.path])),
},
}}
>
<Stack.Navigator>
{routes.map((route) => (
<Stack.Screen
key={route.name}
name={route.name}
component={route.screen}
/>
))}
</Stack.Navigator>
</NavigationContainer>
);
}Screens
NativeLoginScreen— email + password, biometric CTA (opt-in viashowBiometricCta), and links to register / forgot-password.NativeRegisterScreen— email + password + confirm + terms consent with client-side min-length + match validation.NativeMfaChallengeScreen— 6-slot InputOTP with auto-submit on completion. Supportsmethod="totp"/"sms"/"recovery"with matching copy.NativePasswordResetRequestScreen— email + "Send link" CTA transitioning to a "check your inbox" confirmation view on success.NativePasswordResetConfirmScreen— token-driven new-password entry with a dedicated token-invalid error state routing back to the request screen.
Every screen wraps in SafeAreaView from react-native-safe-area-context,
routes copy through useNativeAuthT() (bilingual en/ar), stamps
accessibilityLabel + accessibilityRole on every interactive element, and
enforces a 44×44 minimum touch target on every button.
Related
- ADR-0037 — the 3-package split that motivates this UI kit.
.kiro/steering/ui-components.md— the HeroUI +@stackra/uimandate every component obeys..kiro/skills/heroui-pro-design-taste— 78 principles this package conforms to.
License
MIT © Figentra L.L.C.
