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

cauthy-auth

v0.15.0

Published

Sign in with Cauthy: one route to mount, getSession on the server, useSession in the browser. No database, no screens to build.

Readme

cauthy-auth

Sign your people in with Cauthy: one route to mount, getSession on the server, useSession in the browser.

  • Nothing to build. Sign-in, sign-up, second factors, passkeys, sign-in links, password recovery and the account page are Cauthy's own pages.
  • No database, no migration. The session lives in an encrypted, httpOnly cookie.
  • No token in the browser. The browser asks your server who is signed in.
  • Central control. An account disabled in Cauthy is out of your application within minutes.
npm install cauthy-auth
// auth.ts — reads CAUTHY_ISSUER, CAUTHY_CLIENT_ID, CAUTHY_SECRET (and CAUTHY_SYSTEM)
import { createCauthy } from 'cauthy-auth'
export const auth = createCauthy()
// a route that catches /api/auth/* — any runtime with Request and Response
export const GET = (request: Request) => auth.handler(request)
export const POST = (request: Request) => auth.handler(request)
// on the server
const session = await auth.getSession(request, responseHeaders)
session?.user                           // { id, email, name, emailVerified, restricted }
await auth.organizations(session)       // [{ id, name, role, … }]
// in the browser
import { CauthyProvider, useSession } from 'cauthy-auth/react'
const { session, signIn, signOut } = useSession()

Prefer your own sign-in page to Cauthy's? Set CAUTHY_TENANT and draw it, with the ready-made forms or the functions under them. The browser still holds no token:

import { SignIn, useAuth } from 'cauthy-auth/react'

<SignIn locale="es" links={{ signUp: '/registro', forgotPassword: '/olvide' }} />

const { signIn } = useAuth()
const r = await signIn.email({ email, password })   // r.ok, r.status, r.error.field

What Cauthy mails opens your pages too: a new password, a confirmed address, a sign-in link.

export const auth = createCauthy({ pages: { signIn: '/sign-in', resetPassword: '/new-password', verifyEmail: '/confirm' } })
import { ResetPassword, VerifyEmail } from 'cauthy-auth/react'

And the person's account, in your application: name, password, second step, sessions.

import { Account } from 'cauthy-auth/react'
<Account />                                  // or: const { account } = useAuth()

Roles and permissions with their names, from the catalog Cauthy has:

npx cauthy-auth policy --pull --out src/policy.ts
import { can, hasRole } from './policy'
can(organization, 'ledger:write')            // only what the catalog names compiles

Each framework has its own few lines:

| | | | --- | --- | | Next.js | cauthyNext(auth) from cauthy-auth/next: { GET, POST }, session(), middleware() | | Express | app.use(cauthyExpress(auth)) from cauthy-auth/express: req.cauthy(), requireSession | | Hono | app.use(cauthyHono(auth)) from cauthy-auth/hono: c.get('session'), requireSession | | Fastify | app.register(cauthyFastify, { auth }) from cauthy-auth/fastify: req.cauthy(), app.requireSession | | Anything else | auth.handler(request) takes a Request and answers a Response |

In the browser, beside React:

| | | | --- | --- | | Vue | app.use(createCauthyVue()), then useSession() and useAuth() from cauthy-auth/vue | | Svelte | createCauthySession() from cauthy-auth/svelte: $session, $status, auth | | Anything else | createSessionStore() from cauthy-auth/client |

The ready-made forms wear the look set for your application in Cauthy's dashboard (colours, corners, typeface), the same as Cauthy's own sign-in page, with one import:

import 'cauthy-auth/styles.css'

Or draw them with your own components and classNames, and pass unstyled. The dashboard can start the look from your stylesheet (shadcn/ui and Tailwind, Stackmyth, or variables of your own); npx cauthy-auth theme --css src/app/globals.css reads it the same way from a terminal.

Connect your application to Cauthy in one step, from Cauthy's dashboard ("Connect a System") or from a terminal. In the application's folder, init reads its framework (Next.js, TanStack Start, SvelteKit, Express, Hono, Fastify), makes the client, writes every variable to its env file, CAUTHY_SECRET included, and lays down the route and a sign-in page, never over a file that is there:

npx cauthy-auth init
npx cauthy-auth init --system ledger --app-url https://app.example.com   # production

The same client is your application's own identity: it manages its organizations with no person's token.

const org = await auth.system.organizations.create({ name: 'Acme' })
await auth.system.members.add(org.id, { role: 'owner', email: '[email protected]' })

A backend that is handed a Cauthy access token checks it with Cauthy's published keys: no secret, no call per request.

import { verifyToken } from 'cauthy-auth'
const who = await verifyToken(request)   // throws CauthyTokenError: answer 401
who.userId, who.tenantId, who.roles

An MCP server (or an API) that AI agents use as one of your people: Claude, Cursor and others find Cauthy from it, the person signs in and allows the agent, and the token works on that server alone.

import { mcpAuth } from 'cauthy-auth/mcp'
const auth = mcpAuth({ resource: 'https://mcp.example.com/mcp', scopes: ['books:read'] })
app.use(auth.middleware())                    // or auth.protect(handler) for Request/Response

The full guide is in Cauthy's documentation, under "Auth SDK".

License

Apache-2.0