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

vista-auth

v1.2.13

Published

Simple, powerful, and secure authentication for React apps - works with any framework

Downloads

126

Readme

🔐 Vista Auth

Simple, powerful, and secure authentication for React apps

npm version License: MIT TypeScript

Works with any framework • Any database • Zero configuration needed

Quick StartDocumentationExamplesGitHub


✨ Why Vista Auth?

Vista Auth is a lightweight, production-ready authentication solution that takes 5 minutes to set up and works with any React framework and any database.

Key Features

  • 🚀 Universal Compatibility - Works with Next.js (App & Pages), Remix, Vite, CRA, Express
  • ☁️ Edge Runtime Ready - Runs on Cloudflare Workers, Vercel Edge, and Middleware (powered by jose)
  • 💾 Database Agnostic - Prisma, MongoDB, Supabase, PostgreSQL, Firebase, or in-memory
  • 🔒 Production-Ready Security - bcrypt hashing, JWT tokens, secure sessions
  • 🔑 OAuth Built-in - Google, GitHub, Facebook, Microsoft, Apple providers included
  • 🎯 Minimal Code - 150 lines vs 500+ lines of other solutions
  • 🕵️ Built-in RBAC - Role-based access control with route guards and middleware
  • Real-Time Sync - WebSocket support for multi-tab/device synchronization
  • 🌐 Offline Support - IndexedDB fallback for offline authentication
  • 🎨 Pre-built UI - Professional Login/Signup pages with "Powered by VistaAuth" branding
  • 📦 CLI Auto-Setup - One command to get started with provider setup helpers
  • 🔧 Zero Config Required - Sensible defaults, customize when needed

📦 Installation

npm install vista-auth
yarn add vista-auth
pnpm add vista-auth

🛠️ CLI Commands

Vista Auth includes a comprehensive CLI to help with setup and provide guidance:

Basic Commands

# Initialize new project with interactive setup
npx vista-auth init

# Generate secure authentication secret
npx vista-auth generate-secret

# Show all available commands
npx vista-auth --help

Detailed Help Topics

# Get help with API routes and authentication flow
npx vista-auth --help api

# Learn middleware setup for all frameworks
npx vista-auth --help middleware

# Cookie management and security guidelines
npx vista-auth --help cookies

# Database setup and adapter configuration
npx vista-auth --help database

# Complete implementation examples
npx vista-auth --help examples

What Each Help Topic Covers

  • --help api: Complete API route examples for login, logout, session management with Next.js, Express, and Remix
  • --help middleware: Framework-specific middleware setup for Next.js App Router, Express, Remix, and React Router
  • --help cookies: Cookie security best practices, debugging, and authentication flow management
  • --help database: Database adapter setup for Prisma, MongoDB, Supabase, PostgreSQL, Firebase, and Memory
  • --help examples: Full implementation examples with 5-minute setup guides for each framework

🚀 Quick Start

Step 1: Initialize with CLI

Run the interactive setup wizard:

npx vista-auth init

This creates:

  • vista-auth.config.js - Server configuration
  • app/api/auth/route.js - API endpoints
  • providers.jsx - Client provider setup
  • ✅ Example components

Step 2: Wrap Your App

Next.js App Router:

// app/layout.tsx
import { AuthProvider } from "vista-auth/client";

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

Next.js Pages Router:

// pages/_app.tsx
import { AuthProvider } from "vista-auth/client";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <AuthProvider apiEndpoint="/api/auth">
      <Component {...pageProps} />
    </AuthProvider>
  );
}

Vite:

// src/main.tsx
import { AuthProvider } from "vista-auth/client";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <AuthProvider apiEndpoint="http://localhost:5173/api/auth">
    <App />
  </AuthProvider>
);

Create React App (CRA):

// src/index.tsx
import { AuthProvider } from "vista-auth/client";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <AuthProvider apiEndpoint="http://localhost:3000/api/auth">
    <App />
  </AuthProvider>
);

Step 3: Create Auth API Route

Next.js (App Router):

// app/api/auth/[...vista]/route.ts
import { auth } from "@/vista-auth.config";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  const { action, ...data } = await request.json();

  let result;
  switch (action) {
    case "signIn":
      result = await auth.signIn(data);
      break;
    case "signUp":
      result = await auth.signUp(data);
      break;
    case "signOut":
      // For signOut, we might need the token from the header/cookie
      const token = request.cookies.get("vista-auth-token")?.value;
      if (token) {
        result = await auth.signOut(token);
      } else {
        result = { success: true };
      }
      break;
    default:
      return NextResponse.json(
        { success: false, error: "Invalid action" },
        { status: 400 }
      );
  }

  const response = NextResponse.json(result);

  // Set Secure Cookie if login/signup successful
  if (result.success && result.data?.cookie) {
    response.headers.append("Set-Cookie", result.data.cookie);
  }
  
  // Clear cookie on sign out
  if (action === "signOut") {
     response.cookies.delete("vista-auth-token");
  }

  return response;
}

export async function GET(request: NextRequest) {
  const token = request.cookies.get("vista-auth-token")?.value;
  if (!token) {
    return NextResponse.json({ success: false, error: "No token" }, { status: 401 });
  }
  return NextResponse.json(await auth.getSession(token));
}

Express:

// server.js
import express from "express";
import cookieParser from "cookie-parser";
import { auth } from "./vista-auth.config";

const app = express();
app.use(express.json());
app.use(cookieParser());

app.post("/api/auth", async (req, res) => {
  const { action, ...data } = req.body;

  let result;
  switch (action) {
    case "signIn":
      result = await auth.signIn(data);
      break;
    case "signUp":
      result = await auth.signUp(data);
      break;
    case "signOut":
      const token = req.cookies["vista-auth-token"];
      if (token) await auth.signOut(token);
      res.clearCookie("vista-auth-token");
      return res.json({ success: true });
    case "getSession":
      // ...
      break;
  }

  if (result?.success && result.data?.cookie) {
    res.setHeader("Set-Cookie", result.data.cookie);
  }
  
  res.json(result);
});

🛡️ Middleware

Automatic Generation (Recommended)

When you run npx vista-auth init, the CLI will automatically generate the correct middleware file for your selected framework (Next.js middleware.ts or Express auth-middleware.ts).

Manual Setup

Next.js Middleware:

import { createNextMiddleware } from "vista-auth/middleware";

export default createNextMiddleware({
  publicPaths: ["/login", "/signup", "/", "/about"],
  roleBasedPaths: {
    "/admin/*": ["admin"],
    "/dashboard/*": ["user", "admin"],
  },
  // jwtSecret is now automatically picked up from your config/env
});

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

Express Middleware

import express from "express";
import { createExpressMiddleware } from "vista-auth/middleware";

const app = express();

const authMiddleware = createExpressMiddleware({
  publicPaths: ["/login", "/signup", "/api/public/*"],
  jwtSecret: process.env.VISTA_AUTH_SECRET,
});

app.use(authMiddleware);

app.get("/api/protected", (req, res) => {
  res.json({ message: "Protected data", user: req.user });
});

🔑 OAuth Providers

Vista Auth supports major OAuth providers out of the box with minimal setup.

Supported Providers

  • Google - OAuth 2.0
  • GitHub - OAuth 2.0
  • Facebook - OAuth 2.0
  • Microsoft - OAuth 2.0 (Azure AD)
  • Apple - Sign in with Apple

Quick Setup

Use the CLI to get your OAuth credentials:

npx vista-auth setup-provider google
npx vista-auth setup-provider github

Usage Example

import { GoogleProvider, GitHubProvider } from "vista-auth/providers";
import { createVistaAuth } from "vista-auth/server";

export const auth = createVistaAuth({
  jwtSecret: process.env.VISTA_AUTH_SECRET,
});

// In your OAuth callback route
const googleProvider = new GoogleProvider({
  clientId: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  redirectUri: "http://localhost:3000/api/auth/callback/google",
});

// Exchange code for user profile
const profile = await googleProvider.verify(code);

// Create session
const result = await auth.loginWithProvider({
  email: profile.email,
  name: profile.name,
  image: profile.image,
  provider: "google",
  providerId: profile.id,
});

🎨 Pre-built UI Components

Vista Auth includes professional, customizable UI components.

AuthPage - Complete Login/Signup Page

A beautiful, production-ready authentication page with email/password and social login support.

import { AuthPage } from "vista-auth/ui";
import { createVistaAuth } from "vista-auth/server";
import { redirect } from "next/navigation";
import { cookies } from "next/headers";

const auth = createVistaAuth({ jwtSecret: process.env.VISTA_AUTH_SECRET });

export default function LoginPage() {
  async function handleSignIn(formData: any) {
    "use server";
    const result = await auth.signIn({
      email: formData.email,
      password: formData.password,
    });

    if (result.success && result.data) {
      (await cookies()).set("vista-auth-token", result.data.token);
      redirect("/dashboard");
    }
  }

  async function handleSignUp(formData: any) {
    "use server";
    const result = await auth.signUp({
      email: formData.email,
      password: formData.password,
      name: formData.name,
    });

    if (result.success && result.data) {
      (await cookies()).set("vista-auth-token", result.data.token);
      redirect("/dashboard");
    }
  }

  return (
    <AuthPage
      appName="My App"
      onSignIn={handleSignIn}
      onSignUp={handleSignUp}
      // Optional: Add social login buttons
      socialButtons={
        <div className="grid grid-cols-2 gap-3">
          <button>Google</button>
          <button>GitHub</button>
        </div>
      }
    />
  );
}

Features:

  • ✨ Professional design with dark mode support
  • 🔄 Automatic toggle between Login/Signup
  • ⚡ Built-in loading states and error handling
  • 🎨 Fully customizable with Tailwind CSS
  • 🏷️ "Powered by VistaAuth" branding

Toast Notifications

import { showToast, showError, showWarning, showInfo } from "vista-auth/ui";

showToast("Login successful!", 3000);
showError("Invalid credentials");
showWarning("Session expiring soon");
showInfo("New features available");

🔄 Real-Time Session Sync

Synchronize authentication state across multiple tabs and devices:

<AuthProvider
  apiEndpoint="/api/auth"
  config={{
    sessionSyncEnabled: true,
    websocketUrl: "wss://your-domain.com/ws/auth",
  }}
>
  {children}
</AuthProvider>

🌐 Offline Support

Vista Auth supports offline authentication with IndexedDB:

<AuthProvider
  config={{
    sessionStorage: "indexedDB",
    offlineFallback: true,
  }}
>
  {children}
</AuthProvider>

🔧 API Reference

Client Hooks

useAuth()

const {
  // State
  user, // Current user object or null
  session, // Current session object or null
  isLoading, // true while checking authentication
  isAuthenticated, // true if user is signed in
  error, // Error message if any

  // Actions
  signIn, // (credentials) => Promise<void>
  signUp, // (data) => Promise<void>
  signOut, // () => Promise<void>
  updateUser, // (data) => Promise<void>

  // Role & Permission Checks
  hasRole, // (role: string) => boolean
  hasPermission, // (permission: string) => boolean
  hasAnyRole, // (roles: string[]) => boolean
  hasAllRoles, // (roles: string[]) => boolean
} = useAuth();

Server API

createVistaAuth(config)

import { createVistaAuth } from "vista-auth/server";

const auth = createVistaAuth({
  database: adapter, // Database adapter or null
  jwtSecret: string, // Secret for JWT signing
  bcryptRounds: number, // bcrypt cost factor (default: 10)
  sessionDuration: number, // Session duration in ms
});

// Methods
await auth.signUp({ email, password, name, roles, permissions });
await auth.signIn({ email, password });
await auth.getSession(token);
await auth.signOut(sessionId);
await auth.hashPassword(password);
await auth.verifyPassword(password, hash);
auth.generateToken(payload);
auth.verifyToken(token);

💡 Complete Examples

Full Login Page with Validation

"use client";

import { useState } from "react";
import { useAuth } from "vista-auth/client";
import { showError, showToast } from "vista-auth/ui";

export default function LoginPage() {
  const { signIn, signUp, isLoading } = useAuth();
  const [isSignUp, setIsSignUp] = useState(false);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);

    const email = formData.get("email") as string;
    const password = formData.get("password") as string;
    const name = formData.get("name") as string;

    if (!email || !password) {
      showError("Email and password are required");
      return;
    }

    if (password.length < 8) {
      showError("Password must be at least 8 characters");
      return;
    }

    try {
      if (isSignUp) {
        await signUp({ email, password, name });
        showToast("Account created successfully!");
      } else {
        await signIn({ email, password });
        showToast("Welcome back!");
      }
    } catch (error) {
      showError(error.message || "Authentication failed");
    }
  };

  return (
    <div className="min-h-screen flex items-center justify-center bg-gray-50">
      <div className="max-w-md w-full space-y-8 p-8 bg-white rounded-lg shadow">
        <h2 className="text-3xl font-bold text-center">
          {isSignUp ? "Create Account" : "Sign In"}
        </h2>

        <form onSubmit={handleSubmit} className="space-y-6">
          {isSignUp && (
            <div>
              <label htmlFor="name" className="block text-sm font-medium">
                Name
              </label>
              <input
                id="name"
                name="name"
                type="text"
                className="mt-1 block w-full px-3 py-2 border rounded-md"
                placeholder="John Doe"
              />
            </div>
          )}

          <div>
            <label htmlFor="email" className="block text-sm font-medium">
              Email
            </label>
            <input
              id="email"
              name="email"
              type="email"
              required
              className="mt-1 block w-full px-3 py-2 border rounded-md"
              placeholder="[email protected]"
            />
          </div>

          <div>
            <label htmlFor="password" className="block text-sm font-medium">
              Password
            </label>
            <input
              id="password"
              name="password"
              type="password"
              required
              className="mt-1 block w-full px-3 py-2 border rounded-md"
              placeholder="••••••••"
            />
          </div>

          <button
            type="submit"
            disabled={isLoading}
            className="w-full py-2 px-4 rounded-md text-white bg-blue-600 hover:bg-blue-700 disabled:opacity-50"
          >
            {isLoading ? "Loading..." : isSignUp ? "Sign Up" : "Sign In"}
          </button>
        </form>

        <div className="text-center">
          <button
            onClick={() => setIsSignUp(!isSignUp)}
            className="text-sm text-blue-600 hover:text-blue-500"
          >
            {isSignUp
              ? "Already have an account? Sign in"
              : "Don't have an account? Sign up"}
          </button>
        </div>
      </div>
    </div>
  );
}

Protected Dashboard

"use client";

import { useAuth } from "vista-auth/client";
import { useRequireAuth } from "vista-auth/guards";
import { showToast } from "vista-auth/ui";

export default function DashboardPage() {
  useRequireAuth("/login");

  const { user, signOut, hasRole, hasPermission } = useAuth();

  const handleSignOut = async () => {
    await signOut();
    showToast("Signed out successfully");
  };

  return (
    <div className="min-h-screen bg-gray-100">
      <nav className="bg-white shadow">
        <div className="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
          <h1 className="text-2xl font-bold">Dashboard</h1>
          <button
            onClick={handleSignOut}
            className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
          >
            Sign Out
          </button>
        </div>
      </nav>

      <main className="max-w-7xl mx-auto px-4 py-8">
        <div className="bg-white rounded-lg shadow p-6 mb-6">
          <h2 className="text-xl font-semibold mb-4">Welcome, {user?.name}!</h2>
          <p className="text-gray-600">Email: {user?.email}</p>
          <p className="text-gray-600">
            Roles: {user?.roles?.join(", ") || "None"}
          </p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
          {hasPermission("posts:view") && (
            <div className="bg-white rounded-lg shadow p-6">
              <h3 className="text-lg font-semibold mb-2">Posts</h3>
              <p className="text-gray-600">Manage your posts</p>
            </div>
          )}

          {hasRole("admin") && (
            <div className="bg-white rounded-lg shadow p-6">
              <h3 className="text-lg font-semibold mb-2">Admin Panel</h3>
              <p className="text-gray-600">System administration</p>
            </div>
          )}
        </div>
      </main>
    </div>
  );
}

🛠️ Configuration

Full Configuration Example

// vista-auth.config.ts
import { createVistaAuth } from "vista-auth/server";
import { createPrismaAdapter } from "vista-auth/database";
import { prisma } from "./lib/prisma";

export const auth = createVistaAuth({
  // Database adapter (optional)
  database: createPrismaAdapter(prisma),

  // Security settings
  jwtSecret: process.env.VISTA_AUTH_SECRET!,
  bcryptRounds: 12,
  sessionDuration: 7 * 24 * 60 * 60 * 1000, // 7 days

  // Lifecycle callbacks
  onSignIn: (user) => {
    console.log("User signed in:", user.email);
  },

  onSignOut: () => {
    console.log("User signed out");
  },

  onSessionExpired: () => {
    console.log("Session expired");
  },

  onError: (error) => {
    console.error("Auth error:", error);
  },
});

Environment Variables

Create a .env.local file:

# Required: Secret for JWT signing
VISTA_AUTH_SECRET=your-super-secret-jwt-key-change-in-production

# Optional: Database connection
DATABASE_URL=postgresql://user:password@localhost:5432/myapp

# Optional: WebSocket URL
NEXT_PUBLIC_WS_URL=wss://your-domain.com/ws/auth

🔒 Security Features

  • bcrypt hashing with configurable cost factor
  • JWT tokens with expiration
  • Secure session management
  • CSRF protection ready
  • XSS protection
  • Rate limiting ready
  • Environment variable secrets

📊 Comparison with Other Solutions

| Feature | Vista Auth | NextAuth.js | Clerk | Auth0 | | -------------------------- | ---------- | ----------- | ------ | ------ | | Setup Time | 5 minutes | 30+ minutes | 15 min | 20 min | | Lines of Code | ~150 | 500+ | 200+ | 300+ | | Works Without Database | ✅ | ❌ | ❌ | ✅ | | Database Agnostic | ✅ | ⚠️ | ❌ | ✅ | | Framework Agnostic | ✅ | ❌ | ⚠️ | ✅ | | Built-in RBAC | ✅ | ❌ | ✅ | ✅ | | Real-Time Sync | ✅ | ❌ | ✅ | ✅ | | Offline Support | ✅ | ❌ | ❌ | ❌ | | UI Components | ✅ | ❌ | ✅ | ✅ | | Bundle Size | ~5KB | ~50KB | ~80KB | ~100KB | | Pricing | Free | Free | Paid | Paid | | Self-Hosted | ✅ | ✅ | ❌ | ❌ | | TypeScript First | ✅ | ⚠️ | ✅ | ✅ | | CLI Tool | ✅ | ❌ | ✅ | ❌ |


🤝 Contributing

We welcome contributions from everyone! 🎉

Quick Start for Contributors

  1. Star the repository
  2. 🍴 Fork the project
  3. 🔍 Find an issue labeled good first issue or help wanted
  4. 💻 Make your changes
  5. 📝 Submit a pull request

Ways to Contribute

  • 🐛 Report bugs - Found an issue? Let us know!
  • Suggest features - Have an idea? We'd love to hear it!
  • 📖 Improve docs - Help others understand Vista Auth better
  • 🧪 Write tests - Increase code coverage
  • 🔧 Fix bugs - Help squash those pesky bugs
  • 🎨 Add examples - Show others how to use Vista Auth

Get Started

Recognition

All contributors are recognized in our README and release notes. Significant contributors receive swag and special recognition! 🏆

Join our growing community of contributors! We can't wait to see what you'll build! 💪


📄 License

MIT © Vista Auth


🌟 Why Choose Vista Auth?

  1. Simplicity - 150 lines vs 500+ in alternatives
  2. Flexibility - Works with any React framework and database
  3. Power - Built-in RBAC, real-time sync, offline support
  4. Security - Production-ready with bcrypt and JWT
  5. Developer Experience - TypeScript-first with great docs

📞 Support


Ready to add authentication to your app?

npm install vista-auth
npx vista-auth init

⭐ Star us on GitHub!

https://github.com/ankandalui/vista-auth