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

@re-auth/reauth

v0.1.0-alpha.34

Published

Runtime, framework, and protocol-independent authentication engine for TypeScript/JavaScript applications with plugin-based architecture

Readme

🔐 ReAuth Core - Protocol-Agnostic Authentication Engine

ReAuth Core is a runtime, framework, and protocol-independent authentication engine for TypeScript/JavaScript applications. It provides a universal authentication solution that works across all JS runtimes (Node.js, Deno, Bun, browsers, edge runtimes) and can be integrated with any protocol through dedicated adapters.

🚀 Features

  • 🌐 Runtime Agnostic: Works in Node.js, Deno, Bun, browsers, and edge runtimes
  • 🔌 Protocol Independent: Core engine works with any protocol through dedicated adapters
  • 🎯 Framework Universal: Integrates with any framework through adapter pattern
  • 🧩 Plugin Architecture: Extensible authentication methods (email/password, OAuth, passwordless, custom)
  • 🔒 Session Management: Protocol-agnostic session handling with token support
  • 📡 Auto-Introspection: Automatic API discovery and SDK generation capabilities
  • 💉 Dependency Injection: Clean architecture using Awilix container
  • ✅ Type Safety: Full TypeScript support with comprehensive type definitions
  • 📋 ArkType Validation: Type-safe validation using ArkType

📦 Installation

npm i @re-auth/reauth
# or
yarn add @re-auth/reauth
# or
npm install @re-auth/reauth

🛠️ Getting Started

Protocol-Agnostic Core Setup

The ReAuth core engine is protocol-independent and requires abstract service implementations for entity and session management:

import { ReAuthEngine, emailPasswordAuth } from '@re-auth/reauth';
import { EntityService, SessionService } from '@re-auth/reauth';

// Implement abstract services for your data layer
class MyEntityService implements EntityService {
  async create(data: any) {
    /* Your implementation */
  }
  async findById(id: string) {
    /* Your implementation */
  }
  async findByEmail(email: string) {
    /* Your implementation */
  }
  async update(id: string, data: any) {
    /* Your implementation */
  }
  async delete(id: string) {
    /* Your implementation */
  }
}

class MySessionService implements SessionService {
  async create(entityId: string, data?: any) {
    /* Your implementation */
  }
  async findById(sessionId: string) {
    /* Your implementation */
  }
  async update(sessionId: string, data: any) {
    /* Your implementation */
  }
  async delete(sessionId: string) {
    /* Your implementation */
  }
}

// Initialize your services
const entityService = new MyEntityService();
const sessionService = new MySessionService();

// Create authentication plugins (protocol-agnostic)
const emailPassword = emailPasswordAuth({
  verifyEmail: true,
  loginOnRegister: true,
  async sendCode(entity, code, email, type) {
    // Implement your notification logic (email, SMS, etc.)
    console.log(`Sending ${type} code ${code} to ${email}`);
  },
});

// Initialize the protocol-agnostic auth engine
const auth = new ReAuthEngine({
  plugins: [emailPassword],
  entity: entityService,
  session: sessionService,
  sensitiveFields: {
    password: true,
    token: true,
  },
});

Integration with Protocol Adapters

The core engine integrates with any protocol through dedicated adapters. For HTTP protocol integration, use @re-auth/http-adapters:

// For HTTP protocol integration
import { createHttpAdapter } from '@re-auth/http-adapters';

// The core engine works with any protocol adapter
const httpAdapter = createHttpAdapter(auth, {
  // HTTP-specific configuration
  routes: { prefix: '/auth' },
  introspection: { enabled: true },
});

// Use with your preferred HTTP framework (Express, Fastify, Hono, etc.)

Universal Runtime Compatibility

The same core engine works across all JavaScript runtimes:

// Works in Node.js, Deno, Bun, browsers, edge runtimes
const auth = new ReAuthEngine({
  plugins: [emailPassword],
  entity: entityService, // Your runtime-specific implementation
  session: sessionService, // Your runtime-specific implementation
});

🔌 Built-in Plugins

Email/Password Authentication

import { emailPasswordAuth } from '@re-auth/reauth';

const emailPassword = emailPasswordAuth({
  verifyEmail: true, // Require email verification
  loginOnRegister: true, // Automatically login after registration
  codeType: 'numeric', // Code type for verification/reset ('numeric' | 'alphanumeric' | 'alphabet')
  codeLength: 6, // Length of the verification code
  resetPasswordCodeExpiresIn: 30 * 60 * 1000, // 30 minutes

  // Required for email verification and password reset
  async sendCode(entity, code, email, type) {
    // Send email with the code
    console.log(`Sending ${type} code ${code} to ${email}`);
  },

  // Optional: Custom code generator
  async generateCode(email, entity) {
    return Math.floor(100000 + Math.random() * 900000); // 6-digit code
  },
});

🧩 Creating Custom Plugins

ReAuth supports two types of plugins:

1. Object-Based Plugin

import { AuthPlugin } from '@re-auth/reauth';

const myPlugin: AuthPlugin = {
  name: 'my-auth-plugin',
  version: '1.0.0',

  steps: [
    {
      name: 'authenticate',
      description: 'Custom authentication step',
      async run(input, { container }) {
        // Your authentication logic here
        return {
          success: true,
          message: 'Authenticated successfully',
          status: 'authenticated',
        };
      },
      inputs: ['username', 'password'],
    },
  ],

  initialize(container) {
    // Initialize your plugin here
  },

  getSensitiveFields() {
    return ['password', 'token'];
  },
};

2. Class-Based Plugin

import { AuthPlugin, AuthStep } from '@re-auth/reauth';

export class MyAuthPlugin implements AuthPlugin {
  name = 'my-auth-plugin';
  version = '1.0.0';
  steps: AuthStep[] = [];

  constructor(private container: any) {
    this.steps = [
      {
        name: 'authenticate',
        description: 'Custom authentication step',
        run: this.authenticate.bind(this),
        inputs: ['username', 'password'],
      },
    ];
  }

  private async authenticate(input: any) {
    // Your authentication logic here
    return {
      success: true,
      message: 'Authenticated successfully',
      status: 'authenticated',
    };
  }

  async initialize() {
    // Initialize your plugin here
  }

  getSensitiveFields() {
    return ['password', 'token'];
  }
}

📝 Logging

ReAuth provides comprehensive structured logging through the @re-auth/logger package. All authentication operations, plugin steps, and system events are logged with appropriate tags for easy filtering and debugging.

Logger Configuration

import { createDefaultLogger } from '@re-auth/logger';
import { ReAuthEngine } from '@re-auth/reauth';

// Create a logger instance
const logger = createDefaultLogger({
  prefix: 'MyApp',
  prefixEnv: 'REAUTH_',
  enabledTags: ['auth', 'session', 'plugin'],
  timestampFormat: 'human',
  emojis: true,
});

// Initialize engine with logger
const auth = new ReAuthEngine({
  plugins: [emailPassword],
  entity: entityService,
  session: sessionService,
  logger: logger, // Required logger instance
});

Log Tags

ReAuth uses structured tags to categorize log messages:

  • auth - Core authentication operations (login, logout, verification)
  • session - Session management (creation, validation, expiration)
  • token - Token operations (generation, validation, refresh)
  • jwt - JWT-specific operations (signing, verification, rotation)
  • plugin - Plugin-specific operations (oauth, email, phone, api-key)
  • http - HTTP adapter operations (requests, responses, middleware)
  • engine - Engine operations (step execution, validation, cleanup)
  • database - Database operations (queries, migrations, cleanup)

Environment Variable Control

Control logging via environment variables:

# Enable specific tags
REAUTH_DEBUG=auth,session,plugin

# Enable all tags
REAUTH_DEBUG=*

# Disable all logging
REAUTH_DEBUG=

Production vs Development

  • Development: Beautiful terminal output with colors and emojis
  • Production: Structured JSON logging for log aggregation systems
// Production logging (JSON format)
{"level":"info","tags":["auth"],"message":"User authentication successful","timestamp":"2024-01-15T10:30:00.000Z","prefix":"MyApp"}

// Development logging (pretty format)
[10:30:00am 15 Jan 2024] [MyApp] [auth] ℹ️ User authentication successful

Migration from console.log

If you're upgrading from a version that used console.log, follow this migration guide:

Before (Old Version)

import { ReAuthEngine } from '@re-auth/reauth';

const auth = new ReAuthEngine({
  plugins: [emailPassword],
  entity: entityService,
  session: sessionService,
  // No logger configuration
});

// Console.log statements throughout your code
console.log('User authenticated');
console.warn('Token expired');
console.error('Database connection failed');

After (New Version)

import { ReAuthEngine } from '@re-auth/reauth';
import { createDefaultLogger } from '@re-auth/logger';

// Create logger instance
const logger = createDefaultLogger({
  prefix: 'MyApp',
  enabledTags: ['auth', 'session', 'database'],
});

const auth = new ReAuthEngine({
  plugins: [emailPassword],
  entity: entityService,
  session: sessionService,
  logger: logger, // Required logger instance
});

// Replace console.log with structured logging
logger.info('auth', 'User authenticated');
logger.warn('session', 'Token expired');
logger.error('database', 'Database connection failed');

Key Changes

  1. Add logger dependency: Install @re-auth/logger package
  2. Create logger instance: Use createDefaultLogger() with appropriate configuration
  3. Pass to ReAuthEngine: Logger is now a required parameter
  4. Replace console statements: Use structured logging with appropriate tags
  5. Configure log filtering: Use environment variables to control which logs are shown

Benefits of Migration

  • Structured logging: Consistent format across all log messages
  • Runtime control: Enable/disable logging without code changes
  • Better debugging: Tag-based filtering helps focus on specific issues
  • Production ready: JSON logging for log aggregation systems
  • Beautiful output: Colored terminal output with emojis in development

📚 API Reference

ReAuthEngine

The main protocol-agnostic authentication engine that manages plugins and authentication flows.

const auth = new ReAuthEngine({
  plugins: AuthPlugin[],      // Array of authentication plugins
  entity: EntityService,     // Abstract entity service implementation
  session: SessionService,   // Abstract session service implementation
  logger: LoggerInterface,   // Logger instance for structured logging
  sensitiveFields?: {        // Fields to redact in logs
    [key: string]: boolean;
  };
  authHooks?: AuthHooks[];   // Global authentication hooks
});

Abstract Service Interfaces

The core engine works with abstract service interfaces that you implement for your specific data layer:

EntityService Interface

interface EntityService {
  create(data: any): Promise<any>;
  findById(id: string): Promise<any>;
  findByEmail(email: string): Promise<any>;
  update(id: string, data: any): Promise<any>;
  delete(id: string): Promise<void>;
}

SessionService Interface

interface SessionService {
  create(entityId: string, data?: any): Promise<any>;
  findById(sessionId: string): Promise<any>;
  update(sessionId: string, data: any): Promise<any>;
  delete(sessionId: string): Promise<void>;
}

Protocol-Agnostic Session Management

The core engine provides protocol-independent session management:

// Create a session (works with any protocol)
const session = await auth.createSession(entityId, sessionData);

// Validate a session (protocol-independent)
const validSession = await auth.validateSession(sessionId);

// Introspect authentication capabilities
const capabilities = auth.introspect();

Protocol Adapter Integration

The core engine is designed to work with any protocol through dedicated adapters:

// HTTP Protocol (via @re-auth/http-adapters)
import { createHttpAdapter } from '@re-auth/http-adapters';
const httpAdapter = createHttpAdapter(auth);

// gRPC Protocol (hypothetical future adapter)
import { createWebSocketAdapter } from '@re-auth/grpc-adapters';
const wsAdapter = createGrpcAdapter(auth);

// Custom Protocol (your own adapter)
import { createCustomAdapter } from './my-custom-adapter';
const customAdapter = createCustomAdapter(auth);

🌐 Runtime Compatibility

ReAuth Core works across all JavaScript runtimes without modification:

Node.js

// Standard Node.js usage
import { ReAuthEngine } from '@re-auth/reauth';
const auth = new ReAuthEngine({
  /* config */
});

Deno

// Deno usage (same API)
import { ReAuthEngine } from 'npm:@re-auth/reauth';
const auth = new ReAuthEngine({
  /* config */
});

Bun

// Bun usage (same API)
import { ReAuthEngine } from '@re-auth/reauth';
const auth = new ReAuthEngine({
  /* config */
});

Edge Runtimes & Browsers

// Works in Cloudflare Workers, Vercel Edge, browsers
import { ReAuthEngine } from '@re-auth/reauth';
const auth = new ReAuthEngine({
  /* config */
});

📝 License

MIT

🧱 Plugin Interface

interface AuthPlugin {
  name: string;
  version: string;
  steps: AuthStep[];
  defaultConfig?: Record<string, any>;
  requiredInput?: RequiredInputShape;
  initialize?(container?: AwilixContainer): void | Promise<void>;
}

🪜 Step Structure

Each step is a discrete auth flow like login, register, etc.

interface AuthStep {
  name: string;
  description: string;
  validationSchema?: ValidationSchema;
  run(input: AuthInput): Promise<any>;
  hooks?: {
    before?: HookFunction[];
    after?: HookFunction[];
    onError?: (error: Error, input: AuthInput) => Promise<void>;
  };
}

📑 Validation Schema

type ValidationSchema = Record<string, ((value: any, input: AuthInput) => string | undefined)[]>;

You can also use ArkType for validation (see ArkType Validation Support below).

✅ Required Input Flags

Defines what the plugin step expects:

interface RequiredInputShape {
  reqBody?: boolean;
  reqQuery?: boolean;
  reqParams?: boolean;
  reqHeaders?: boolean;
  reqMethod?: boolean;
}

🪝 Hook Types

type HookFunction = (input: AuthInput, output?: any) => Promise<void>;

🚦Plugin Lifecycle

The lifecycle of a plugin follows these steps:

⚠️ Object Plugin Restrictions

  • ❌ Do not use this in run functions or hooks.
  • ✅ Capture context using top-level variables or closures.
  • ⚠️ If plugin requires internal state, switch to class format.

🧪 Example Registry

export const authPlugins: AuthPlugin[] = [emailPasswordPlugin, new MagicLinkPlugin(), new OauthPlugin()];

✅ Summary

| Format | this Allowed | Lifecycle Support | Best For | | ------------ | -------------- | ----------------- | --------------------------- | | Object-based | ❌ No | ✅ Yes | Lightweight plugins | | Class-based | ✅ Yes | ✅ Yes | Stateful or complex plugins |

🔄 ArkType Validation Support

ReAuth uses ArkType for type-safe validation throughout the authentication engine.

Using ArkType in a Plugin

import { type } from 'arktype';

// Define schemas using ArkType
const emailSchema = type('string.email');
const passwordSchema = type('string.alphanumeric >= 8');

// Use ArkType validation in your plugin
const myPlugin: AuthPlugin = {
  name: 'my-auth-plugin',
  version: '1.0.0',
  steps: [
    {
      name: 'login',
      description: 'Login with email and password',
      async run(input) {
        // Validate input using ArkType
        const emailResult = emailSchema(input.email);
        const passwordResult = passwordSchema(input.password);

        if (emailResult instanceof type.errors) {
          throw new Error('Invalid email format');
        }

        if (passwordResult instanceof type.errors) {
          throw new Error('Password must be at least 8 alphanumeric characters');
        }

        // Your authentication logic here
        return { success: true };
      },
    },
  ],
};

Direct ArkType Validation

You can use ArkType directly for data validation:

import { type } from 'arktype';

const userSchema = type({
  email: 'string.email',
  password: 'string.alphanumeric >= 8',
});

// Validate data
const result = userSchema({
  email: '[email protected]',
  password: 'password123',
});

if (result instanceof type.errors) {
  console.error('Validation failed:', result.summary);
} else {
  console.log('Valid user data:', result);
}