
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@insforge/react
Advanced tools
Framework-agnostic React authentication UI components for Insforge - reusable across all frameworks
Complete authentication solution for React applications. Framework-agnostic components with full business logic included.
✅ Complete Package - Not just UI, includes SDK integration, providers, and hooks
✅ Framework Agnostic - Works with Next.js, Vite, Remix, or any React framework
✅ 5-Minute Setup - Provider + Components = done
✅ Full TypeScript - Complete type safety out of the box
✅ Customizable - Every component supports appearance props and text customization
Need just UI? All components are exported separately for maximum flexibility.
npm install @insforge/react
# or
yarn add @insforge/react
# or
pnpm add @insforge/react
Dependencies automatically include @insforge/sdk for authentication logic.
Wrap your app with InsforgeProvider in the root:
// React / Vite
import { InsforgeProvider } from '@insforge/react';
import '@insforge/react/styles.css';
function App() {
return (
<InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
{/* Your app */}
</InsforgeProvider>
);
}
// Next.js App Router
'use client';
import { InsforgeProvider } from '@insforge/react';
import '@insforge/react/styles.css';
export default function RootLayout({ children }) {
return (
<html>
<body>
<InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}>
{children}
</InsforgeProvider>
</body>
</html>
);
}
Props:
baseUrl (required): Your Insforge backend URLonAuthChange (optional): Callback when auth state changessyncTokenToCookie (optional): Custom function to sync token to cookies (for Next.js SSR)clearCookie (optional): Custom function to clear cookie on sign outThe easiest way to add authentication:
'use client'; // for Next.js
import { SignIn, SignUp } from '@insforge/react';
// Sign In Page
export default function SignInPage() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<SignIn
afterSignInUrl="/dashboard"
signUpUrl="/sign-up"
/>
</div>
);
}
// Sign Up Page
export default function SignUpPage() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<SignUp
afterSignUpUrl="/dashboard"
signInUrl="/sign-in"
/>
</div>
);
}
Handle OAuth redirects:
'use client'; // for Next.js
import { InsforgeCallback } from '@insforge/react';
export default function CallbackPage() {
return <InsforgeCallback />;
}
'use client'; // for Next.js
import { SignedIn, SignedOut, UserButton, useAuth, useUser } from '@insforge/react';
export default function Home() {
const { isSignedIn } = useAuth();
const { user } = useUser();
return (
<div>
<SignedOut>
<a href="/sign-in">Sign In</a>
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
<h1>Welcome, {user?.email}!</h1>
</SignedIn>
</div>
);
}
That's it! 🎉 Your React app now has production-ready authentication.
1. User visits Sign In page → Renders <SignIn> component
↓
2. User enters credentials → Component calls SDK methods
↓
3. SDK communicates with backend → Returns auth token
↓
4. Provider updates auth state → Components re-render
↓
5. User sees authenticated UI → Redirect to dashboard
Architecture:
@insforge/sdkThese components include full authentication logic:
<SignIn />Complete sign-in component with email/password and OAuth:
import { SignIn } from '@insforge/react';
import { useNavigate } from 'react-router-dom';
function SignInPage() {
const navigate = useNavigate();
return (
<SignIn
afterSignInUrl="/dashboard"
signUpUrl="/sign-up"
forgotPasswordUrl="/forgot-password"
onSuccess={(user, accessToken) => {
console.log('Signed in:', user);
}}
onError={(error) => {
console.error('Error:', error);
}}
onRedirect={(url) => navigate(url)}
// Customization
title="Welcome Back"
subtitle="Sign in to continue"
appearance={{
containerClassName: "shadow-xl",
buttonClassName: "bg-blue-600"
}}
/>
);
}
Key Features:
<SignUp />Complete sign-up component with password strength validation:
import { SignUp } from '@insforge/react';
function SignUpPage() {
return (
<SignUp
afterSignUpUrl="/onboarding"
signInUrl="/sign-in"
onSuccess={(user, accessToken) => {
// Track sign-up event
analytics.track('user_signed_up', { userId: user.id });
}}
/>
);
}
Key Features:
<UserButton />User profile dropdown with sign-out:
import { UserButton } from '@insforge/react';
function Header() {
return (
<header>
<nav>
{/* Your navigation */}
</nav>
<UserButton
afterSignOutUrl="/"
mode="detailed" // or "simple"
appearance={{
buttonClassName: "hover:bg-gray-100",
nameClassName: "text-gray-900",
emailClassName: "text-gray-600"
}}
/>
</header>
);
}
Modes:
detailed: Shows avatar + name + emailsimple: Shows avatar only<Protect />Protected content with conditional rendering:
import { Protect } from '@insforge/react';
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
{/* Simple protection */}
<Protect redirectTo="/sign-in">
<UserContent />
</Protect>
{/* Role-based protection */}
<Protect
redirectTo="/unauthorized"
condition={(user) => user.role === 'admin'}
>
<AdminPanel />
</Protect>
</div>
);
}
<SignedIn> / <SignedOut>Conditional rendering based on auth state:
import { SignedIn, SignedOut } from '@insforge/react';
function NavBar() {
return (
<nav>
<SignedOut>
<a href="/sign-in">Sign In</a>
<a href="/sign-up">Sign Up</a>
</SignedOut>
<SignedIn>
<a href="/dashboard">Dashboard</a>
<UserButton />
</SignedIn>
</nav>
);
}
<InsforgeCallback />OAuth callback handler (3 lines instead of 70+):
'use client';
import { InsforgeCallback } from '@insforge/react';
export default function CallbackPage() {
return <InsforgeCallback redirectTo="/dashboard" />;
}
useAuth()Access authentication methods:
import { useAuth } from '@insforge/react';
function LoginButton() {
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
const handleSignIn = async () => {
try {
await signIn('user@example.com', 'password');
// Redirect or update UI
} catch (error) {
console.error('Sign in failed:', error);
}
};
if (!isLoaded) return <div>Loading...</div>;
return (
<button onClick={isSignedIn ? signOut : handleSignIn}>
{isSignedIn ? 'Sign Out' : 'Sign In'}
</button>
);
}
Returns:
signIn(email, password) - Sign in with email/passwordsignUp(email, password) - Sign up new usersignOut() - Sign out current userisSignedIn - Boolean auth stateisLoaded - Boolean loading stateuseUser()Access user data:
import { useUser } from '@insforge/react';
function UserProfile() {
const { user, isLoaded, updateUser } = useUser();
if (!isLoaded) return <div>Loading...</div>;
if (!user) return <div>Not signed in</div>;
const handleUpdate = async () => {
await updateUser({ name: 'New Name' });
};
return (
<div>
<p>Email: {user.email}</p>
<p>Name: {user.name}</p>
<img src={user.avatarUrl} alt="Avatar" />
<button onClick={handleUpdate}>Update Name</button>
</div>
);
}
Returns:
user - User object with id, email, name, avatarUrlisLoaded - Boolean loading stateupdateUser(data) - Update user profilesetUser(user) - Manually set user stateusePublicAuthConfig()Get OAuth providers and password requirements:
import { usePublicAuthConfig } from '@insforge/react';
function SignInPage() {
const { oauthProviders, emailConfig, isLoaded } = usePublicAuthConfig();
if (!isLoaded) return <div>Loading...</div>;
return (
<div>
<p>Available OAuth: {oauthProviders.join(', ')}</p>
<p>Password min length: {emailConfig?.passwordMinLength}</p>
</div>
);
}
⚠️ Important: Only use this hook in SignIn/SignUp components to avoid unnecessary API calls.
Build custom auth flows with pre-built forms:
<SignInForm />import { SignInForm } from '@insforge/react';
import { useState } from 'react';
function CustomSignIn() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
// Your auth logic
};
return (
<SignInForm
email={email}
password={password}
onEmailChange={setEmail}
onPasswordChange={setPassword}
onSubmit={handleSubmit}
error={error}
loading={loading}
availableProviders={['google', 'github']}
onOAuthClick={(provider) => handleOAuth(provider)}
/>
);
}
Other Form Components:
<SignUpForm /> - Sign up with password strength<ForgotPasswordForm /> - Request password reset<ResetPasswordForm /> - Reset password with token<VerifyEmailStatus /> - Email verification statusBuild completely custom UIs:
import {
AuthContainer,
AuthHeader,
AuthFormField,
AuthPasswordField,
AuthSubmitButton,
AuthErrorBanner,
AuthDivider,
AuthOAuthProviders,
AuthLink,
} from '@insforge/react';
function CompletelyCustomAuth() {
return (
<AuthContainer
appearance={{
containerClassName: "max-w-md",
cardClassName: "bg-white shadow-2xl"
}}
>
<AuthHeader
title="Welcome to MyApp"
subtitle="Sign in to continue"
appearance={{
titleClassName: "text-3xl text-blue-900"
}}
/>
<AuthErrorBanner error={error} />
<form onSubmit={handleSubmit}>
<AuthFormField
id="email"
type="email"
label="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
appearance={{
inputClassName: "border-blue-500"
}}
/>
<AuthPasswordField
id="password"
label="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
emailAuthConfig={config}
showStrengthIndicator
/>
<AuthSubmitButton isLoading={loading}>
Sign In
</AuthSubmitButton>
</form>
<AuthDivider text="or" />
<AuthOAuthProviders
providers={['google', 'github', 'discord']}
onClick={handleOAuth}
loading={oauthLoading}
/>
<AuthLink
text="Don't have an account?"
linkText="Sign up"
href="/sign-up"
/>
</AuthContainer>
);
}
Available Atomic Components:
AuthContainer - Main wrapper with brandingAuthHeader - Title and subtitleAuthErrorBanner - Error messagesAuthFormField - Standard inputAuthPasswordField - Password with toggleAuthPasswordStrengthIndicator - Password checklistAuthSubmitButton - Loading buttonAuthLink - Navigation linkAuthDivider - Visual separatorAuthOAuthButton - Single OAuth buttonAuthOAuthProviders - OAuth gridAuthVerificationCodeInput - 6-digit OTPAuthBranding - Insforge brandingAll components support Tailwind className overrides:
<SignIn
appearance={{
containerClassName: "shadow-2xl max-w-lg",
cardClassName: "bg-gradient-to-br from-blue-50 to-white",
formClassName: "space-y-6",
buttonClassName: "bg-blue-600 hover:bg-blue-700 h-12"
}}
/>
<UserButton
appearance={{
buttonClassName: "hover:bg-gray-100 rounded-full",
nameClassName: "text-gray-900 font-semibold",
emailClassName: "text-gray-500",
dropdownClassName: "shadow-xl"
}}
/>
All text is customizable:
<SignIn
title="Welcome Back!"
subtitle="We're happy to see you again"
emailLabel="Your Email Address"
emailPlaceholder="you@company.com"
passwordLabel="Your Password"
submitButtonText="Login Now"
loadingButtonText="Signing you in..."
signUpText="New to our platform?"
signUpLinkText="Create an account"
dividerText="or continue with"
/>
// app/layout.tsx
'use client';
import { InsforgeProvider } from '@insforge/react';
import '@insforge/react/styles.css';
export default function RootLayout({ children }) {
return (
<html>
<body>
<InsforgeProvider
baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}
syncTokenToCookie={async (token) => {
await fetch('/api/auth', {
method: 'POST',
body: JSON.stringify({ token })
});
return true;
}}
clearCookie={async () => {
await fetch('/api/auth', { method: 'DELETE' });
}}
>
{children}
</InsforgeProvider>
</body>
</html>
);
}
// src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { InsforgeProvider } from '@insforge/react';
import '@insforge/react/styles.css';
import App from './App';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
<App />
</InsforgeProvider>
</BrowserRouter>
</StrictMode>
);
// app/root.tsx
import { InsforgeProvider } from '@insforge/react';
import '@insforge/react/styles.css';
export default function App() {
return (
<html>
<body>
<InsforgeProvider baseUrl={process.env.INSFORGE_BASE_URL}>
<Outlet />
</InsforgeProvider>
</body>
</html>
);
}
Full TypeScript support with exported types:
import type {
InsforgeUser,
SignInProps,
SignUpProps,
UserButtonProps,
ProtectProps,
ConditionalProps,
InsforgeCallbackProps,
SignInFormProps,
SignUpFormProps,
AuthFormFieldProps,
OAuthProvider,
EmailAuthConfig,
InsforgeProviderProps,
} from '@insforge/react';
interface InsforgeProviderProps {
baseUrl: string; // Insforge backend URL
onAuthChange?: (user: InsforgeUser | null) => void; // Auth state callback
syncTokenToCookie?: (token: string) => Promise<boolean>; // Custom cookie sync
clearCookie?: () => Promise<void>; // Custom cookie clear
}
interface SignInProps {
afterSignInUrl?: string; // Redirect after sign in
signUpUrl?: string; // Link to sign up page
forgotPasswordUrl?: string; // Link to forgot password
onSuccess?: (user, token) => void; // Success callback
onError?: (error: Error) => void; // Error callback
onRedirect?: (url: string) => void; // Custom redirect handler
title?: string; // Custom title
subtitle?: string; // Custom subtitle
appearance?: { // Custom styling
containerClassName?: string;
cardClassName?: string;
formClassName?: string;
buttonClassName?: string;
};
// ... more text customization props
}
interface InsforgeCallbackProps {
redirectTo?: string; // Custom redirect destination
onSuccess?: () => void; // Success callback
onError?: (error: string) => void; // Error callback
loadingComponent?: ReactNode; // Custom loading UI
onRedirect?: (url: string) => void; // Custom redirect handler
}
import { emailSchema, cn } from '@insforge/react';
// Validate email with Zod
const result = emailSchema.safeParse('user@example.com');
// Merge Tailwind classes
const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
Built-in support for 10+ OAuth providers:
Providers are auto-detected from your backend configuration.
vs. Building Custom Auth:
vs. Other Auth Libraries:
Check out example integrations:
MIT © Insforge
FAQs
Framework-agnostic React authentication UI components for Insforge - reusable across all frameworks
The npm package @insforge/react receives a total of 668 weekly downloads. As such, @insforge/react popularity was classified as not popular.
We found that @insforge/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.