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

@payez/next-mvp

v3.6.0

Published

PayEz IDP authentication package for Next.js 14/15 with pre-built UI components and complete authentication flow.

Readme

@payez/next-mvp

PayEz IDP authentication package for Next.js 14/15 with pre-built UI components and complete authentication flow.

Version History

v2.4.2 (2025-11-14)

  • Fixed: Redirect loop on token expiration - middleware now allows NextAuth JWT callback to refresh expired tokens instead of immediately redirecting to login, preventing infinite redirect loops when access tokens expire

v2.4.1 (2025-11-14)

  • Fixed: Stale cookie detection - viability API now properly detects when JWT exists but Redis session is missing, preventing access with expired sessions
  • Fixed: Token refresh field names - changed to PascalCase (RefreshToken, AuthenticationMethods, AuthenticationLevel, TwoFactorMethod) to match IDP requirements, resolving 400 errors during token refresh

v2.4.0

  • Auth-ready v2 handlers with pre-configured routes
  • Redis session management improvements
  • Token refresh optimizations

Features

  • 🔐 Complete Authentication Flow - Login, logout, session management, password recovery
  • 🎨 Pre-built UI Components - Ready-to-use login, recovery, and verify-code pages
  • 🔄 Automatic Token Refresh - Built-in refresh token handling
  • 🎭 Themeable - Customize branding, colors, and layout via ThemeProvider
  • 📱 Responsive Design - Mobile-first Tailwind CSS components
  • 🚀 Next.js 14/15 Ready - Works with App Router and React Server Components
  • 🔒 Secure by Default - JWT-based authentication with PayEz IDP

Installation

npm install @payez/next-mvp next-auth
# or
yarn add @payez/next-mvp next-auth

Peer Dependencies

Ensure you have these installed:

npm install next@^14.0.0 next-auth@^4.24.7 react@^18.2.0 react-dom@^18.2.0

Development Scripts

PayEz MVP includes convenient development scripts for getting started quickly:

npm run dev:local

Local Development Mode - Perfect for first-time setup and testing without an external IDP:

  • Auto-generates NEXTAUTH_SECRET for you
  • No external IDP connection required
  • Great for UI development and testing
npm run dev:local

This will:

  1. Generate a secure random NEXTAUTH_SECRET
  2. Display the secret (save it to your .env.local)
  3. Start the Next.js dev server on port 3000

npm run dev:broker

Broker Mode - Production-like authentication with PayEz IDP:

  • Uses OAuth/OIDC flow with PayEz IDP
  • Client assertion authentication
  • Required for testing real authentication flows
  • This is a core feature for PayEz MVP users
npm run dev:broker

This will:

  1. Enable broker mode (USE_BROKER_MODE=true)
  2. Set client ID for IDP authentication
  3. Start the Next.js dev server on port 3000
  4. Automatically kills any existing process on port 3000

Custom Port & Client ID:

# In your consuming project's package.json
"scripts": {
  "dev:broker": "pwsh -NoProfile -ExecutionPolicy Bypass -File node_modules/@payez/next-mvp/scripts/dev-broker.ps1 -ClientId 2 -Port 3400"
}

Which Script to Use?

| Scenario | Script | When to Use | |----------|--------|-------------| | 🎨 UI Development | dev:local | Building components, testing UI flows | | 🔐 Auth Testing | dev:broker | Testing real OAuth flows, token management | | 🚀 Production-like | dev:broker | Testing with actual IDP integration |


Quick Start (App Router with UI Components)

1. Configure Next.js

Add to your next.config.ts:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  transpilePackages: ['@payez/next-mvp'],
};

export default nextConfig;

2. Set Environment Variables

Create .env.local (or .env.development) in your project root:

# PayEz IDP Configuration (required)
CLIENT_ID=your_client_slug_from_payez    # e.g., "payez_idp_admin_web"
IDP_URL=https://idp.payez.net            # or http://localhost:32785 for local dev

# NextAuth trusts request headers for OAuth callback URLs
AUTH_TRUST_HOST=true

# NEXTAUTH_SECRET - DO NOT SET!
# The MVP broker fetches this securely from IDP at startup.
# Only set manually if you need to override the IDP-provided secret.

# Optional
REDIS_URL=redis://localhost:6379         # For session storage
NEXT_PUBLIC_IDP_BASE_URL=https://idp.payez.net  # For client-side redirects

Note: NEXTAUTH_SECRET is intentionally omitted. The MVP automatically fetches it from the IDP at startup using the broker pattern. See Environment Variables Reference for details.

3. Create NextAuth API Route

Create app/api/auth/[...nextauth]/route.ts:

/**
 * NextAuth API Route Handler
 * Uses pre-configured handler from @payez/next-mvp
 */
export { GET, POST } from '@payez/next-mvp/routes/auth/nextauth';

4. Wrap Your App with Providers

Create app/providers.tsx:

'use client';

import { SessionProvider } from 'next-auth/react';
import { ThemeProvider } from '@payez/next-mvp/theme';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <SessionProvider>
      <ThemeProvider>
        {children}
      </ThemeProvider>
    </SessionProvider>
  );
}

Update app/layout.tsx:

import { Providers } from './providers';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  );
}

5. Add Authentication Pages

Login Page - app/account-auth/login/page.tsx:

'use client';

import LoginPage from '@payez/next-mvp/dist/pages/login';

export default function LoginPageWrapper() {
  return <LoginPage />;
}

Password Recovery - app/account-auth/recovery/page.tsx:

'use client';

import RecoveryPage from '@payez/next-mvp/dist/pages/recovery';

export default function RecoveryPageWrapper() {
  return <RecoveryPage />;
}

Verify Code (2FA) - app/account-auth/verify-code/page.tsx:

'use client';

import VerifyCodePage from '@payez/next-mvp/dist/pages/verify-code';

export default function VerifyCodePageWrapper() {
  return <VerifyCodePage />;
}

6. Protect Routes with Authentication

Server-side protection:

import { getServerSession } from 'next-auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await getServerSession();

  if (!session) {
    redirect('/account-auth/login');
  }

  return (
    <div>
      <h1>Welcome, {session.user?.email}</h1>
    </div>
  );
}

Client-side hook:

'use client';

import { useSession } from 'next-auth/react';

export default function ProfilePage() {
  const { data: session, status } = useSession();

  if (status === 'loading') return <div>Loading...</div>;
  if (status === 'unauthenticated') return <div>Access Denied</div>;

  return <div>Logged in as {session?.user?.email}</div>;
}

Advanced: V2 Middleware-Based Setup

For applications requiring middleware-based route protection:

1. Configure Public Routes

Create src/lib/auth.ts:

import { configurePublicRoutes, createAuthOptions } from '@payez/next-mvp';
import CredentialsProvider from 'next-auth/providers/credentials';

// Define routes that do NOT require authentication
const publicRoutes = [
  '/',
  '/login',
  '/api/health',
  '/api/public/*', // Wildcard example
];

configurePublicRoutes(publicRoutes);

export const authOptions = createAuthOptions({
  credentialsProvider: CredentialsProvider,
  // Additional NextAuthOptions can be passed here
});

export { authOptions as GET, authOptions as POST } from './auth';

2. Setup NextAuth API Route

For Pages Router (pages/api/auth/[...nextauth].ts):

import NextAuth from 'next-auth';
import { authOptions } from '../../../src/lib/auth';

export default NextAuth(authOptions);

For App Router (app/api/auth/[...nextauth]/route.ts):

export { GET, POST } from '../../../src/lib/auth';

3. Implement Middleware

Create middleware.ts at project root:

import { createMvpMiddleware } from '@payez/next-mvp';

export default createMvpMiddleware();

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

4. Use fetchWithAuth for Protected API Calls

import { fetchWithAuth } from '@payez/next-mvp';

async function fetchData() {
  try {
    const response = await fetchWithAuth('/api/protected-data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Failed to fetch protected data:', error);
  }
}

5. Session Viability API Handler

For Pages Router (pages/api/session/viability.ts):

import viabilityHandler from '@payez/next-mvp/api-handlers/session/viability';

export default viabilityHandler;

For App Router (app/api/session/viability/route.ts):

export { default as GET } from '@payez/next-mvp/api-handlers/session/viability';

Custom Theming

Customize branding and colors:

// lib/mvp-theme-config.ts
import { ThemeConfig } from '@payez/next-mvp/theme';

const customTheme: ThemeConfig = {
  branding: {
    companyName: "Your Company",
    logoUrl: "/logo.svg",
    logoAlt: "Your Company Logo"
  },
  colors: {
    primary: "#3b82f6",      // Blue
    primaryHover: "#2563eb",
    secondary: "#10b981",    // Green
    danger: "#ef4444",       // Red
    text: "#1f2937",
    textLight: "#6b7280",
    background: "#ffffff",
    backgroundAlt: "#f9fafb",
    border: "#e5e7eb"
  },
  layout: {
    maxWidth: "28rem",       // max-w-md
    padding: "1.5rem",       // p-6
    borderRadius: "0.5rem"   // rounded-lg
  }
};

export default customTheme;

Then use in your Providers:

import customTheme from '@/lib/mvp-theme-config';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <SessionProvider>
      <ThemeProvider theme={customTheme}>
        {children}
      </ThemeProvider>
    </SessionProvider>
  );
}

API Routes

Access pre-built API handlers:

// Session validation
import { GET as validateSession } from '@payez/next-mvp/routes/auth/session';

// Token refresh
import { POST as refreshToken } from '@payez/next-mvp/routes/auth/refresh';

// Logout
import { POST as logout } from '@payez/next-mvp/routes/auth/logout';

Environment Variables Reference

| Variable | Required | Description | |----------|----------|-------------| | CLIENT_ID | ✅ Yes | Your PayEz IDP client ID (string slug, e.g., payez_idp_admin_web) | | IDP_URL | ✅ Yes | PayEz IDP base URL (e.g., https://idp.payez.net or http://localhost:32785) | | AUTH_TRUST_HOST | ✅ Yes | Must be true - NextAuth derives OAuth URLs from request headers | | NEXTAUTH_SECRET | 🔄 Broker | Do NOT set - fetched automatically from IDP at startup (see below) | | CLIENT_SECRET | ⚠️ Legacy | Not needed with broker mode - IDP handles signing | | NEXT_PUBLIC_IDP_BASE_URL | ⚠️ Optional | Public-facing IDP URL (for client-side redirects) | | REDIS_URL | ⚠️ Optional | Redis connection string for session storage |

NEXTAUTH_SECRET Broker Flow

The MVP uses a "broker" pattern for NEXTAUTH_SECRET - the IDP securely provides it at startup rather than storing it in env files.

┌─────────────────────────────────────────────────────────────┐
│  App Startup (instrumentation.ts → ensureInitialized)       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  Is NEXTAUTH_SECRET set and non-empty?                      │
└─────────────────────────────────────────────────────────────┘
            │                              │
          YES                             NO (recommended)
            │                              │
            ▼                              ▼
   ┌─────────────┐         ┌─────────────────────────────────┐
   │ Use as-is   │         │ Fetch from IDP (Broker Mode)    │
   │ (override)  │         │   1. Sign client assertion      │
   │             │         │   2. POST to /next-auth/secret  │
   │             │         │   3. Set process.env at runtime │
   └─────────────┘         └─────────────────────────────────┘

Key points:

  • Do NOT set NEXTAUTH_SECRET in .env files - leave it undefined
  • The IDP provides the secret securely at startup via client assertion
  • Secret is cached for 5 minutes, then re-fetched if needed
  • If you DO set it manually, that value takes precedence (useful for overrides)
  • The broker needs CLIENT_ID and IDP_URL to fetch the secret

Troubleshooting

SessionProvider Error

If you see useSession must be wrapped in a <SessionProvider />:

  1. Ensure transpilePackages: ['@payez/next-mvp'] is in next.config.ts
  2. Make sure all page components using PayEz components have 'use client' directive
  3. Verify your app is wrapped with <Providers> in layout.tsx

Module Resolution Errors

If you get Module not found errors:

  1. Clear Next.js cache: rm -rf .next
  2. Reinstall dependencies: npm install
  3. Restart dev server

Authentication Not Working

  1. Verify CLIENT_ID and IDP_URL are set correctly
  2. Check CLIENT_ID matches your PayEz IDP configuration (use the slug, not numeric ID)
  3. Verify IDP is running and reachable at IDP_URL
  4. Check server logs for broker startup messages - look for "NEXTAUTH_SECRET Successfully Fetched from IDP"
  5. If secret fetch fails, check IDP logs for client assertion errors
  6. Check browser console for error messages

NEXTAUTH_SECRET Issues

"NEXTAUTH_SECRET not available" error:

  • This means the broker couldn't fetch the secret from IDP
  • Check that IDP_URL is correct and IDP is running
  • Verify CLIENT_ID is registered in the IDP
  • Check network connectivity between your app and IDP

Cookie cross-contamination (localhost development):

  • If running multiple apps on localhost (different ports), NextAuth cookies can conflict
  • Clear next-auth.* cookies in browser, or use incognito
  • Each app uses a unique cookie name based on CLIENT_ID to avoid conflicts

Docker/CI Deployment (IMPORTANT)

When consuming @payez/next-mvp via a local .tgz file in Docker builds, you must use a local path reference.

The Problem

If your package.json references the MVP like this:

"@payez/next-mvp": "file:../PayEz-Next-MVP/packages/next-mvp/payez-next-mvp-2.6.50.tgz"

Docker builds will fail with:

npm error ENOENT: no such file or directory, open '/PayEz-Next-MVP/packages/next-mvp/payez-next-mvp-2.6.50.tgz'

The relative path ../ resolves incorrectly inside the Docker container's /app working directory.

The Fix

  1. Copy the .tgz file into your project root:

    cp ../PayEz-Next-MVP/packages/next-mvp/payez-next-mvp-*.tgz ./
  2. Update package.json to use a local reference:

    "@payez/next-mvp": "file:./payez-next-mvp-2.6.50.tgz"
  3. Run npm install to update package-lock.json

  4. Ensure your Dockerfile copies the tgz:

    COPY payez-next-mvp-*.tgz ./

Quick Fix Script

Run this in your consuming project to fix the path:

# Copy latest tgz
cp ../PayEz-Next-MVP/packages/next-mvp/payez-next-mvp-*.tgz ./

# Update package.json path (adjust version as needed)
sed -i 's|file:../PayEz-Next-MVP/packages/next-mvp/|file:./|g' package.json

# Regenerate lockfile
npm install --legacy-peer-deps

After MVP Version Updates

When you update the MVP package version, repeat steps 1-3 to copy the new .tgz and update references.


Pre-Publishing Checklist (For Package Maintainers)

Before publishing this package to npm:

✅ Code Quality

  • [x] All @/ path aliases converted to relative paths
  • [x] TypeScript compiles without errors: npm run build
  • [x] No hardcoded configuration values (use env variables)
  • [ ] Unit tests pass (if implemented)

📦 Package Configuration

CRITICAL FIXES NEEDED:

  1. Fix main field in package.json (Line 5):

    "main": "dist/index.js",  // NOT "src/index.ts"
  2. Remove unused tsc-alias from devDependencies (Line 542):

    // DELETE this line:
    "tsc-alias": "^1.8.16"
  3. Add package metadata:

    {
      "description": "PayEz IDP authentication package for Next.js with ready-to-use login, recovery, and profile pages",
      "keywords": ["nextjs", "authentication", "next-auth", "payez", "idp", "oauth"],
      "author": "PayEz Team",
      "license": "MIT",
      "repository": {
        "type": "git",
        "url": "https://github.com/your-org/PayEz-Next-MVP"
      },
      "homepage": "https://github.com/your-org/PayEz-Next-MVP#readme",
      "bugs": {
        "url": "https://github.com/your-org/PayEz-Next-MVP/issues"
      }
    }

📝 Documentation

  • [x] README.md is complete and accurate
  • [ ] CHANGELOG.md exists with version history
  • [ ] LICENSE file exists

🧪 Testing

  • [ ] Test fresh installation in new Next.js 14 project
  • [ ] Test fresh installation in new Next.js 15 project
  • [ ] Verify all exported modules work
  • [ ] Test with React 18 and React 19
  • [ ] Test package build: npm pack --dry-run

🚀 Publishing Steps

# 1. Fix package.json issues (see above)

# 2. Login to npm
npm login

# 3. Build package
npm run build

# 4. Preview what will be published
npm pack --dry-run

# 5. Test the tarball locally
npm install ./payez-next-mvp-2.3.1.tgz

# 6. Bump version (patch/minor/major)
npm version patch  # 2.3.1 -> 2.3.2
npm version minor  # 2.3.1 -> 2.4.0
npm version major  # 2.3.1 -> 3.0.0

# 7. Publish to npm
npm publish

# 8. Create git tag and push
git push origin main
git push origin --tags

📋 .npmignore

Create .npmignore to exclude unnecessary files:

src/
*.test.ts
*.test.tsx
tsconfig.json
.gitignore
.git
node_modules/
*.tgz
.env*

🔒 Publish Configuration

Add to package.json:

"publishConfig": {
  "access": "public",
  "registry": "https://registry.npmjs.org/"
}

📚 Complete Documentation

Core Guides

  • THEMING.md - Complete guide to customizing auth components

    • Theme structure and configuration
    • Creating light/dark modes
    • Component-specific customization
    • Common theming issues and solutions
  • CSS_VARIABLES_INTEGRATION.md - CSS variable injection for MVP components

    • Why CSS variables are needed
    • How to inject variables in your app
    • Color conversion utilities
    • Debugging CSS variable issues
  • THEME_EXAMPLES.md - Ready-to-use theme examples

    • 7 pre-built professional themes
    • Multi-brand theme support
    • Dynamic light/dark mode
    • Copy-paste theme configurations

Topics Covered

Theming

  • ✅ Brand colors and logos
  • ✅ Light and dark modes
  • ✅ Font families and typography
  • ✅ Layout and spacing customization
  • ✅ Component-specific styling
  • ✅ Multi-tenant/white-label setups
  • ✅ Accessibility and contrast

CSS Variables

  • ✅ Understanding CSS custom properties
  • ✅ Manual variable injection
  • ✅ Color conversion (Tailwind → hex)
  • ✅ Theme provider pattern
  • ✅ Dynamic theme switching
  • ✅ Debugging in DevTools

Examples

  • ✅ Corporate themes
  • ✅ SaaS themes
  • ✅ Creative/design themes
  • ✅ Accessible high-contrast themes
  • ✅ Multi-brand configurations
  • ✅ Gradient backgrounds
  • ✅ Custom branding

Quick Links

Getting Started with Themes:

  1. Start with THEMING.md - Quick Start section
  2. Copy a theme from THEME_EXAMPLES.md
  3. Follow integration pattern in CSS_VARIABLES_INTEGRATION.md

For Specific Tasks:


License

MIT

Support

For issues and questions:

  • GitHub Issues: https://github.com/your-org/PayEz-Next-MVP/issues
  • Documentation: https://docs.payez.net

Contributing

Contributions welcome! Please read our contributing guidelines first.


Made with ❤️ by the PayEz Team