passji
raw JSON → 0.0.2 verified Sat Apr 25 auth: no javascript
Passji is an OIDC-based authentication service that uses emoji identities and WebAuthn passkeys instead of passwords. Version 0.0.2 is currently available. It provides SDKs for React, Next.js (Auth.js), Better Auth, Express, Hono, and Passport.js. Key differentiators: pseudonymous by default (no email required), AI-native API keys for agents, and emoji-based user identity. It ships TypeScript types and is designed for modern web and AI agent authentication flows.
Common errors
error Cannot find module 'passji/client' ↓
cause Import from 'passji/client' but the package is not installed or version is old.
fix
Install passji: npm install passji@latest
error Passji is not defined (NextAuth) ↓
cause Importing Passji as default but using named import.
fix
Use: import Passji from 'passji/nextauth' (default import)
error Uncaught TypeError: Cannot destructure property 'signIn' of '(0 , ...).usePassji(...)' as it is undefined. ↓
cause usePassji hook used outside of PassjiProvider.
fix
Wrap your component tree with <PassjiProvider> before using usePassji.
error TypeError: client.createAuthorizationURL is not a function ↓
cause Imported createClient from 'passji' instead of 'passji/client'.
fix
Change import to: import { createClient } from 'passji/client'
Warnings
breaking Import paths differ by framework: /client, /server, /react, /nextauth, /better-auth, /passport. Importing from 'passji' only gives core types. ↓
fix Use the correct subpath import for your framework (e.g., 'passji/react' for React).
gotcha The client-side createClient() must be used only in browser environments; it generates PKCE code verifiers. Do not import from 'passji/server' on the client. ↓
fix Ensure server-side code uses 'passji/server' and client-side uses 'passji/client'.
deprecated No deprecations known yet for version 0.0.2.
gotcha The React provider requires an onToken callback to send the token to your own API; it does not automatically handle server-side validation. ↓
fix Implement your own /api/auth endpoint that uses createServer to verify the token.
gotcha Express integration requires express-session to be installed; the package declares it as a peer dependency. ↓
fix Install express-session: npm install express-session
Install
npm install passji yarn add passji pnpm add passji Imports
- createClient wrong
import { createClient } from 'passji'correctimport { createClient } from 'passji/client' - createServer wrong
import { createServer } from 'passji'correctimport { createServer } from 'passji/server' - PassjiProvider wrong
import { PassjiProvider } from 'passji'correctimport { PassjiProvider, usePassji } from 'passji/react' - Passji (NextAuth) wrong
import { Passji } from 'passji/nextauth'correctimport Passji from 'passji/nextauth' - passji (Better Auth) wrong
import passji from 'passji/better-auth'correctimport { passji } from 'passji/better-auth'
Quickstart
import { createClient } from 'passji/client';
import { createServer } from 'passji/server';
import { PassjiProvider, usePassji } from 'passji/react';
// Client-side: generate authorization URL with PKCE
const client = createClient({
clientId: process.env.PASSJI_CLIENT_ID ?? '',
redirectUri: 'http://localhost:3000/callback'
});
const { url, codeVerifier } = await client.createAuthorizationURL();
// Server-side: exchange code for tokens
const server = createServer({
clientId: process.env.PASSJI_CLIENT_ID ?? '',
clientSecret: process.env.PASSJI_CLIENT_SECRET ?? '',
redirectUri: 'http://localhost:3000/callback'
});
const tokens = await server.exchangeCode('code', codeVerifier);
const user = await server.verifyIdToken(tokens.idToken);
console.log(user.emojiId);
// React: use PassjiProvider and usePassji
function App() {
return (
<PassjiProvider clientId={process.env.PASSJI_CLIENT_ID ?? ''} onToken={(token) => fetch('/api/auth', { method: 'POST', body: JSON.stringify({ token }) })}>
<LoginButton />
</PassjiProvider>
);
}
function LoginButton() {
const { signIn, user } = usePassji();
if (user) return <span>{user.emojiId}</span>;
return <button onClick={signIn}>Sign in</button>;
}