Remix Auth

4.2.0 · active · verified Wed Apr 22

remix-auth is a TypeScript-first, strategy-based authentication library designed for Remix and React Router applications. Inspired by Passport.js, it provides full server-side authentication capabilities built on the Web Fetch API, ensuring compatibility with modern web standards. The library is currently stable at version 4.2.0 and maintains an active release cadence, frequently introducing new features, bug fixes, and documentation improvements. Key differentiators include its robust TypeScript support, extensible strategy pattern (with separate npm packages for various authentication flows like Form, OAuth2, etc.), and seamless integration with Remix's server-side action and loader functions, allowing developers to implement custom authentication logic. It dropped direct React Router requirements in v4.0.0, simplifying its core and making it more adaptable.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates the core setup of `remix-auth` with `FormStrategy`, including session storage configuration, `Authenticator` instantiation, strategy registration, and integration into Remix `action` and `loader` functions for user login and authentication checks.

import { Form } from '@remix-run/react';
import { Authenticator } from 'remix-auth';
import { FormStrategy } from 'remix-auth-form';
import { createCookieSessionStorage, redirect } from '@remix-run/node';
import type { ActionArgs, LoaderArgs } from '@remix-run/node';

// 1. Define your User type
interface User { id: string; email: string; name: string; }

// 2. Setup session storage
const sessionStorage = createCookieSessionStorage({
  cookie: {
    name: '__session',
    httpOnly: true,
    path: '/',
    sameSite: 'lax',
    secrets: [process.env.SESSION_SECRET ?? 's3cr3t'], // Use an environment variable for secrets
    secure: process.env.NODE_ENV === 'production',
  },
});

// 3. Create Authenticator instance
export let authenticator = new Authenticator<User>(sessionStorage);

// 4. Register a strategy (e.g., FormStrategy)
authenticator.use(
  new FormStrategy(async ({ form }) => {
    let email = form.get('email') as string;
    let password = form.get('password') as string;

    // Simulate user login
    if (email === 'test@example.com' && password === 'password') {
      return { id: '123', email, name: 'Test User' };
    }
    throw new Error('Invalid credentials');
  }),
  'user-pass' // Name of the strategy
);

// 5. Create a Login route (app/routes/login.tsx)
export default function Screen() {
  return (
    <Form method='post'>
      <input type='email' name='email' required placeholder='Email' />
      <input
        type='password'
        name='password'
        autoComplete='current-password'
        required
        placeholder='Password'
      />
      <button type='submit'>Sign In</button>
    </Form>
  );
}

// 6. Handle authentication in the action function
export async function action({ request }: ActionArgs) {
  try {
    let user = await authenticator.authenticate('user-pass', request, {
      successRedirect: '/',
      failureRedirect: '/login?error=true',
    });
    return user; // Should not reach here if redirects work
  } catch (error) {
    // This catch block handles redirect responses thrown by authenticate
    // or other errors. Remix will re-throw the response.
    throw error;
  }
}

// 7. Example loader to check authentication
export async function loader({ request }: LoaderArgs) {
  let user = await authenticator.isAuthenticated(request);
  if (!user) {
    throw redirect('/login');
  }
  return { user };
}

view raw JSON →