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

@glitch_protocol/auth-react

v0.2.0

Published

React hooks and components for glitch_protocol

Readme

@glitch_protocol/auth-react

React hooks and components for glitch_protocol. Provides a context provider, session management hooks, and pre-built UI components for displaying active sessions.

Install

npm install @glitch_protocol/auth-react @glitch_protocol/auth-client react react-dom socket.io-client zustand

Setup

1. Create auth client and store (see @glitch_protocol/auth-client)

// lib/auth.ts
import { createglitch_protocolClient, createAuthStore, createSocketClient } from "@glitch_protocol/auth-client";

let getToken = () => null as string | null;
let onRefreshed = (t: string) => {};
let onCleared = () => {};

export const client = createglitch_protocolClient({
  baseUrl: "http://localhost:4000",
  getAccessToken: () => getToken(),
  onTokenRefreshed: (t) => onRefreshed(t),
  onAuthCleared: () => onCleared(),
});

export const useAuthStore = createAuthStore({ client });
getToken = () => useAuthStore.getState().accessToken;
onRefreshed = (t) => useAuthStore.getState().setAccessToken(t);
onCleared = () => useAuthStore.getState().clearAuth();

export const socketClient = createSocketClient({
  serverUrl: "http://localhost:4000",
  getAccessToken: () => useAuthStore.getState().accessToken,
});

2. Wrap your app with glitch_protocolProvider

// app.tsx
import { glitch_protocolProvider } from "@glitch_protocol/auth-react";
import { useAuthStore, socketClient } from "./lib/auth";

export default function App() {
  return (
    <glitch_protocolProvider store={useAuthStore} socketClient={socketClient}>
      <Dashboard />
    </glitch_protocolProvider>
  );
}

Hooks

useAuth

Access auth state and operations.

function useAuth(): {
  user: AuthUser | null;
  accessToken: string | null;
  isLoading: boolean;
  isInitialized: boolean;
  login: (email: string, password: string) => Promise<{ success: boolean; error?: string }>;
  register: (name: string, email: string, password: string) => Promise<{ success: boolean; error?: string }>;
  logout: () => Promise<void>;
}

Example:

function Dashboard() {
  const { user, isLoading, isInitialized, logout } = useAuth();

  if (!isInitialized) return <Spinner />;
  if (!user) return <LoginForm />;

  return (
    <div>
      <p>Welcome, {user.name}</p>
      <button onClick={logout}>Sign out</button>
    </div>
  );
}

login / register: Both return { success: true } on success or { success: false, error: "message" } on failure. Automatically set auth state on success.

function LoginForm() {
  const { login } = useAuth();

  const handleSubmit = async (email: string, password: string) => {
    const result = await login(email, password);
    if (result.success) {
      // Redirect to dashboard (done by state change)
    } else {
      toast.error(result.error);
    }
  };

  return <form onSubmit={handleSubmit}>...</form>;
}

useSessions

Access active sessions and termination.

function useSessions(): {
  sessions: SessionInfo[];
  terminateSession: (sessionId: string) => Promise<void>;
  terminateOtherSessions: () => Promise<void>;
}

Example:

function SessionManager() {
  const { sessions, terminateSession, terminateOtherSessions } = useSessions();

  return (
    <div>
      <h2>Your Devices</h2>
      {sessions.map((session) => (
        <div key={session.id}>
          <p>{session.browser} on {session.os}</p>
          <p>{session.ipAddress}</p>
          <p>{new Date(session.lastActivity).toLocaleString()}</p>
          <button onClick={() => terminateSession(session.id)}>
            Sign out
          </button>
        </div>
      ))}
      <button onClick={terminateOtherSessions}>
        Sign out all other devices
      </button>
    </div>
  );
}

useSocket

Access the Socket.IO client for custom event listeners.

function useSocket(): {
  socket: Socket | null;
  isConnected: boolean;
  getSocket: () => Socket | null;
}

Example:

function ConnectionStatus() {
  const { isConnected, socket } = useSocket();

  useEffect(() => {
    if (!socket) return;

    socket.on("custom:event", (data) => {
      console.log("Received:", data);
    });

    return () => socket.off("custom:event");
  }, [socket]);

  return <span>{isConnected ? "🟢 Online" : "🔴 Offline"}</span>;
}

Components

SessionCard

Displays a single session with termination button.

interface SessionCardProps {
  session: SessionInfo;
  onTerminate?: (sessionId: string) => Promise<void>;
  isCurrent?: boolean;
}

export function Dashboard() {
  const { sessions, terminateSession } = useSessions();

  return (
    <>
      {sessions.map((session) => (
        <SessionCard
          key={session.id}
          session={session}
          isCurrent={session.id === currentSessionId}
          onTerminate={terminateSession}
        />
      ))}
    </>
  );
}

Rendered:

┌─ Chrome on Windows ──────────────────┐
│ 192.168.1.100                        │
│ Last activity: 2 minutes ago          │
│ [Signed in 3 days ago]       [Sign out] │
└──────────────────────────────────────┘

SessionManager

Pre-built session management UI with list and bulk actions.

export function SettingsPage() {
  return (
    <div>
      <h1>Settings</h1>
      <SessionManager />
    </div>
  );
}

Features:

  • Lists all active sessions
  • Marks current session as "This device"
  • Button to terminate each session individually
  • Button to "Sign out all other devices"
  • Real-time updates when new session created or terminated

Real-Time Events

The provider automatically connects to Socket.IO and listens for events:

  • session:new — New login detected on another device
  • session:terminated — A session was terminated
  • session:list-updated — Session list changed (e.g., activity update)

State is automatically updated when these events arrive. No manual handling needed.

Custom listeners:

function MyComponent() {
  const { socket } = useSocket();

  useEffect(() => {
    if (!socket) return;

    socket.on("session:new", (session) => {
      toast.info(`New login from ${session.browser}`);
    });

    return () => socket.off("session:new");
  }, [socket]);

  return null;
}

Example: Complete App

// app.tsx
import { useEffect } from "react";
import { glitch_protocolProvider, useAuth, useSessions } from "@glitch_protocol/auth-react";
import { useAuthStore, socketClient } from "./lib/auth";

function App() {
  return (
    <glitch_protocolProvider store={useAuthStore} socketClient={socketClient}>
      <Layout />
    </glitch_protocolProvider>
  );
}

function Layout() {
  const initialize = useAuthStore((s) => s.initialize);
  const isInitialized = useAuthStore((s) => s.isInitialized);

  useEffect(() => {
    initialize();
  }, [initialize]);

  if (!isInitialized) return <Spinner />;

  return (
    <div>
      <Header />
      <Router>
        <Route path="/" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Router>
    </div>
  );
}

function Header() {
  const { user, logout } = useAuth();

  return (
    <nav>
      <div>Hello, {user?.name}</div>
      <button onClick={logout}>Sign out</button>
    </nav>
  );
}

function Dashboard() {
  const { user } = useAuth();
  const { sessions } = useSessions();

  return (
    <div>
      <h1>Dashboard</h1>
      <p>You have {sessions.length} active session(s)</p>
      {sessions.map((session) => (
        <SessionCard key={session.id} session={session} />
      ))}
    </div>
  );
}

function Settings() {
  return (
    <div>
      <h1>Settings</h1>
      <SessionManager />
    </div>
  );
}

export default App;

Peer Dependencies

  • react: >=18.0.0 — React library
  • react-dom: >=18.0.0 — React DOM library
  • @glitch_protocol/auth-client: ^0.1.0 — Browser SDK
  • socket.io-client: ^4.8.0 — Real-time events
  • zustand: ^5.0.0 — State management

Node Version

ESM-only. Requires Node.js >=18.