npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@freshheads/react-auth

v0.0.2

Published

A type-safe React authentication library for Next.js and react applications with built-in role-based access control (RBAC) and JWT token management. Based on our own authentication backend.

Readme

@freshheads/react-auth

A type-safe React authentication library for Next.js and react applications with built-in role-based access control (RBAC) and JWT token management. Based on our own authentication backend.

Features

  • 🔐 Authentication Management - Built-in login/logout functionality with JWT token handling
  • 🛡️ Role-Based Access Control (RBAC) - Define route access based on user roles
  • 🎯 Type-Safe - Full TypeScript support with generic types for routes and roles
  • 🚀 Next.js Middleware Integration - Server-side route protection
  • 🪝 React Hooks - Easy-to-use hooks for authentication state and utilities
  • 🍪 Cookie Management - Automatic JWT cookie handling

Installation

npm install @freshheads/react-auth

Peer Dependencies

This package requires the following peer dependencies:

npm install react react-dom next @tanstack/react-query typescript

Requirements

  • React: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
  • Next.js: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
  • TypeScript: ^5.0.0
  • @tanstack/react-query: ^5.95.2

Usage

1. Define Your Configuration

Create a configuration object that defines your routes, roles, and API mutations:

import { ReactAuthConfig } from '@freshheads/react-auth';


const appRoutes = ['/login', '/dashboard', '/admin', '/profile'] as const; // these are placeholders. Normally generated by next.js
const appRoles = ['admin', 'user'] as const; // these are placeholders. Normally generated by backend

const authConfig: ReactAuthConfig<
  typeof AppRoutes, 
  typeof AppRoles[],    
  typeof usePasswordLoginPost,
  typeof useLogoutPost> = {
  // Define role-based routes
  rbacRoutes: {
    admin: {
      routes: ['/admin'],
      landing: '/admin',
    },
    user: {
      routes: ['/dashboard', '/profile'],
      landing: '/dashboard',
    },
  },
  
  // Default routes
  defaultRoutes: {
    login: '/login',
    landing: '/dashboard', // this is the default landing page when there is no landing page defined for a role
  },
  
  // Routes accessible to everyone
  openRoutes: ['/about', '/contact'],
  
  // Routes only accessible when NOT authenticated
  unauthenticatedRoutes: ['/login', '/register'],
  
  // Authorized roles
  authorizedRoles: appRoles,
  
  // Locale prefix support (e.g. /en/dashboard). based on next-intl
  withLocaleRoutePrefix: false,
  
  // API mutation functions pass in the mutation generated by Orval
  apiMutations: {
        loginUsernamePassword: usePasswordLoginPost,
        logout: useLogoutPost,
  },
  
  // Optional: Custom cookie name (default: 'jwt_hp')
  cookieName: 'jwt_hp',
};

export default authConfig;

2. Set Up Next.js Middleware

Create or update your middleware.ts or proxy.ts file:

import { withAuth } from '@freshheads/react-auth/server';
import authConfig from './auth.config';

export default withAuth(authConfig);

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

3. Wrap Your App with AuthConfigProvider

In your root layout or app component:

'use client';

import { AuthConfigProvider } from '@freshheads/react-auth/client';
import authConfig from './auth.config';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AuthConfigProvider config={authConfig}>
          {children}
        </AuthConfigProvider>
      </body>
    </html>
  );
}

4. Use Authentication Hooks

Check User Authentication and Roles

'use client';

import { useAuthUser } from '@freshheads/react-auth/client';

export default function Dashboard() {
  const { roles, hasRole } = useAuthUser<'admin' | 'user'>();

  if (!roles) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>Dashboard</h1>
      {hasRole('admin') && <AdminPanel />}
      {hasRole('user') && <UserPanel />}
    </div>
  );
}

Login with Username and Password

'use client';

import { useUsernamePasswordLogin } from '@freshheads/react-auth/client';

export default function LoginForm() {
  const { login } = useUsernamePasswordLogin();

  const handleSubmit = async (e) => {
    e.preventDefault();
    await login({ username: 'user', password: 'pass' });
  };

  return <form onSubmit={handleSubmit}>{/* form fields */}</form>;
}

Logout

'use client';

import { useLogout } from '@freshheads/react-auth/client';

export default function LogoutButton() {
  const { logout } = useLogout();

  return <button onClick={() => logout()}>Logout</button>;
}

Get Role from Path

'use client';

import { useAuthUtils } from '@freshheads/react-auth/client';

export default function Navigation() {
  const { getRoleFromPath } = useAuthUtils();

  const adminRole = getRoleFromPath('/admin');
  // Returns the role required to access the path

  return <nav>{/* navigation */}</nav>;
}

Access Auth Configuration

'use client';

import { useAuthConfig } from '@freshheads/react-auth/client';

export default function MyComponent() {
  const config = useAuthConfig();

  // Access any configuration property
  console.log(config.defaultRoutes.login);
  console.log(config.authorizedRoles);

  return <div>...</div>;
}

5. Server-Side Utilities

Get Roles from Request Cookies (Server-Side)

import { getRolesFromRequestCookies } from '@freshheads/react-auth/server';
import { cookies } from 'next/headers';

export async function GET() {
  const cookieStore = await cookies();
  const userRoles = getRolesFromRequestCookies(cookieStore);

  return Response.json({ roles: userRoles });
}

Get Role from Path (Server-Side)

import { getRoleFromPath } from '@freshheads/react-auth/server';

const requiredRole = getRoleFromPath('/admin');
// Returns 'admin'

6. Utility Functions

Check if User Has a Specific Role

import { userHasRole } from '@freshheads/react-auth/client';

const isAdmin = await userHasRole('admin');

Get Roles from Cookies

import { getRolesFromCookies } from '@freshheads/react-auth/client';

const roles = await getRolesFromCookies();
// Returns array of user roles or null

Configuration Options

ReactAuthConfig

| Property | Type | Description | |----------|------|-------------| | rbacRoutes | RbacRoutes | Maps roles to their accessible routes and landing pages | | defaultRoutes | { login: ValidRoute, landing: ValidRoute } | Default login and landing routes | | openRoutes | ValidRoute[] | Routes accessible to everyone (authenticated or not) | | unauthenticatedRoutes | ValidRoute[] | Routes only accessible when NOT authenticated | | authorizedRoles | AuthorizedRoles | Array of valid roles in your application | | withLocaleRoutePrefix | boolean | Whether routes have locale prefixes (e.g., /en/dashboard) | | apiMutations | { loginUsernamePassword, logout } | API mutation functions for auth operations | | cookieName | string (optional) | Custom cookie name (default: 'jwt_hp') |

RbacRoutes

type RbacRoutes<ValidRoute, AuthorizedRoles extends string[]> = {
  [key in AuthorizedRoles[number]]: {
    routes: ValidRoute[];
    landing?: ValidRoute;
  };
};

How It Works

  1. Middleware Protection: The withAuth middleware intercepts all requests and checks:

    • If the route requires authentication
    • If the user has the required role for the route
    • Redirects unauthenticated users to the login page
    • Redirects authenticated users away from unauthenticated-only routes
  2. JWT Token Management: User roles are stored in a JWT token in cookies. The library automatically:

    • Parses the JWT to extract user roles
    • Validates authentication state
    • Provides hooks to access user information
  3. Role-Based Access: Routes are protected based on the roles defined in rbacRoutes. Users can only access routes that match their assigned roles.

TypeScript Support

This library is built with TypeScript and provides full type safety:

// Define your specific types
type MyRoutes = '/home' | '/dashboard' | '/admin';
type MyRoles = 'user' | 'admin' | 'moderator';

// Get full type checking and autocomplete
const config: ReactAuthConfig<MyRoutes, MyRoles[]> = {
  // TypeScript will validate all routes and roles
};

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.