auth0-js, jsonwebtoken, oidc-client, and passport are all related to authentication in JavaScript applications, but they operate in fundamentally different layers and contexts. auth0-js is a deprecated frontend SDK specifically for Auth0's authentication service. jsonwebtoken is a Node.js utility for signing and verifying JSON Web Tokens, intended for server-side use only. oidc-client is a deprecated generic OpenID Connect client for browsers, designed to work with any OIDC-compliant identity provider. passport is an actively maintained authentication middleware for Node.js applications, commonly used with Express to handle various authentication strategies like local credentials, JWT, or OAuth providers. Understanding where each package fits — frontend vs backend, generic vs provider-specific, and current vs deprecated status — is crucial for secure and maintainable architecture.
When building modern web applications, handling user identity securely is non-negotiable. The four packages — auth0-js, jsonwebtoken, oidc-client, and passport — all relate to authentication but serve very different roles in the stack. Confusing them leads to architectural mistakes, like using a low-level JWT utility for frontend login flows or trying to run a server-side strategy on the client. Let’s clarify where each belongs.
auth0-js: Frontend SDK for Auth0auth0-js is a browser-only library provided by Auth0 to handle authentication flows with their platform. It wraps OAuth 2.0 and OpenID Connect (OIDC) protocols specifically for Auth0’s implementation. You use it to log users in via redirects or popups, get ID/access tokens, and manage sessions — but only if you’re using Auth0 as your identity provider.
// auth0-js: Login and get user info
import Auth0 from 'auth0-js';
const webAuth = new Auth0.WebAuth({
domain: 'your-tenant.auth0.com',
clientID: 'your-client-id',
redirectUri: 'https://your-app.com/callback',
responseType: 'token id_token'
});
webAuth.authorize(); // Redirects to Auth0 login
// Later, in callback handler:
webAuth.parseHash((err, authResult) => {
if (!err) {
const { idTokenPayload } = authResult;
console.log('User:', idTokenPayload);
}
});
⚠️ Important: This package is deprecated as of 2021. Auth0 recommends migrating to
@auth0/auth0-spa-jsfor new projects. Avoidauth0-jsin greenfield development.
jsonwebtoken: Low-Level JWT Encoding/Decodingjsonwebtoken is a server-side (Node.js) utility for creating and verifying JSON Web Tokens. It has no knowledge of OAuth, OIDC, or browser flows. You use it when you need to mint tokens after validating credentials (e.g., in a custom login API) or validate tokens sent by clients.
// jsonwebtoken: Sign and verify tokens (Node.js only)
import jwt from 'jsonwebtoken';
// After validating username/password
const token = jwt.sign({ userId: 123 }, 'secret-key', { expiresIn: '1h' });
// Later, verify an incoming token
const decoded = jwt.verify(token, 'secret-key');
console.log(decoded.userId); // 123
❗ This package should never run in the browser. It requires access to secret keys, which would be exposed to users. Use it only in trusted backend environments.
oidc-client: Generic OIDC Client for Browsersoidc-client is a frontend library that implements the OpenID Connect protocol generically — not tied to any specific provider like Auth0. It handles token storage, silent renewals, and PKCE flow, making it suitable for apps that need to integrate with any OIDC-compliant identity server (e.g., IdentityServer, Okta, Keycloak).
// oidc-client: Generic OIDC login
import { UserManager } from 'oidc-client';
const userManager = new UserManager({
authority: 'https://your-oidc-server.com',
client_id: 'your-client-id',
redirect_uri: 'https://your-app.com/callback',
response_type: 'code',
scope: 'openid profile'
});
userManager.signinRedirect(); // Starts OIDC flow
// In callback page:
userManager.signinRedirectCallback().then(user => {
console.log('Access token:', user.access_token);
});
⚠️ Important: As of 2023,
oidc-clientis deprecated. The maintainers recommend migrating tooidc-client-ts, a TypeScript rewrite with active support. Do not start new projects withoidc-client.
passport: Authentication Middleware for Node.jspassport is a server-side framework for authenticating requests in Express (or other Node.js web servers). It uses “strategies” (e.g., passport-local, passport-jwt, passport-google-oauth20) to handle different auth methods. It never runs in the browser — it processes credentials sent by frontend clients.
// passport: Local username/password strategy (Express.js)
import passport from 'passport';
import { Strategy as LocalStrategy } from 'passport-local';
passport.use(new LocalStrategy(
async (username, password, done) => {
const user = await db.findUser(username);
if (!user || !verifyPassword(password, user.password)) {
return done(null, false);
}
return done(null, user);
}
));
// In route handler:
app.post('/login',
passport.authenticate('local', { session: false }),
(req, res) => {
// req.user is available here
const token = jwt.sign({ id: req.user.id }, 'secret');
res.json({ token });
}
);
✅
passportis actively maintained and widely used in Node.js backends. It’s not deprecated.
| Package | Environment | Can Run in Browser? | Can Run in Node.js? |
|---|---|---|---|
auth0-js | Frontend only | ✅ Yes | ❌ No |
jsonwebtoken | Backend only | ❌ No (unsafe) | ✅ Yes |
oidc-client | Frontend only | ✅ Yes | ❌ No |
passport | Backend only | ❌ No | ✅ Yes |
Mixing these up causes critical errors:
jsonwebtoken in frontend code leaks secrets.passport in a React app does nothing — it needs an HTTP server.auth0-js with a non-Auth0 provider won’t work.Creating tokens: Only jsonwebtoken (on the server) should generate JWTs. Frontend libraries like auth0-js or oidc-client receive tokens from identity providers — they don’t create them.
Consuming tokens: Frontend apps use auth0-js or oidc-client to store tokens (in memory or secure cookies) and attach them to API requests. Backend APIs use passport (with passport-jwt) or direct jsonwebtoken.verify() calls to validate tokens.
// Backend: Verify token sent by frontend (using jsonwebtoken directly)
app.get('/protected', (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
try {
const decoded = jwt.verify(token, 'secret-key');
res.json({ message: 'OK', user: decoded });
} catch (err) {
res.status(401).json({ error: 'Invalid token' });
}
});
// Backend: Same thing, but with passport-jwt strategy
import { Strategy as JwtStrategy } from 'passport-jwt';
passport.use(new JwtStrategy({ secretOrKey: 'secret-key', jwtFromRequest: ... },
(payload, done) => done(null, payload)
));
app.get('/protected', passport.authenticate('jwt', { session: false }), (req, res) => {
res.json({ user: req.user });
});
In a typical full-stack app:
oidc-client-ts (successor to oidc-client) or @auth0/auth0-spa-js (successor to auth0-js) to authenticate the user and obtain tokens.Authorization header.passport with passport-jwt (which internally uses jsonwebtoken) to validate the token and authorize the request.You would never use auth0-js and passport in the same layer — one is frontend, the other backend.
auth0-js: Deprecated. Use @auth0/auth0-spa-js instead.oidc-client: Deprecated. Use oidc-client-ts instead.jsonwebtoken: Actively maintained. Safe for backend use.passport: Actively maintained. Standard in Node.js auth.If you’re starting a new project:
oidc-client-ts (generic) or @auth0/auth0-spa-js (Auth0-specific).passport + strategies or jsonwebtoken directly.| Scenario | Recommended Package(s) |
|---|---|
| Building a React app with Auth0 | @auth0/auth0-spa-js (not auth0-js) |
| Building a React app with any OIDC provider | oidc-client-ts (not oidc-client) |
| Validating JWTs in a Node.js API | passport + passport-jwt or jsonwebtoken |
| Creating custom JWTs after login | jsonwebtoken (server only) |
| Implementing username/password login backend | passport + passport-local |
Choose based on layer (frontend vs backend) and protocol (generic OIDC vs Auth0-specific). Never mix responsibilities — keep token creation on the server, and leave browser flows to dedicated frontend SDKs.
Avoid auth0-js in new projects — it is officially deprecated by Auth0. If you're integrating with Auth0 specifically, use its modern replacement @auth0/auth0-spa-js, which offers better security (PKCE by default), smaller bundle size, and ongoing support. Only consider legacy auth0-js if maintaining an old application that hasn't been migrated yet.
Choose jsonwebtoken when you need to programmatically sign or verify JWTs in a Node.js backend environment — for example, issuing tokens after successful login or validating tokens in protected API routes. Never use it in frontend code, as it requires access to secret keys that must remain confidential. It’s a low-level tool; pair it with frameworks like Express or authentication middleware like Passport for complete solutions.
Do not use oidc-client for new development — it is deprecated and no longer maintained. Instead, adopt its official successor oidc-client-ts, which provides the same generic OpenID Connect functionality with TypeScript support and active updates. Use this family of libraries only when you need a standards-compliant OIDC client for the browser that works with any identity provider like IdentityServer, Okta, or Keycloak.
Choose passport when building a Node.js backend (typically with Express) that needs flexible, strategy-based authentication — such as supporting local username/password, social logins (Google, GitHub), or JWT validation. It’s a mature, well-tested middleware that handles request authentication cleanly. Remember, Passport runs only on the server; it should never be included in frontend bundles.

📚 Documentation - 🚀 Getting Started - 💻 API Reference - 💬 Feedback
From CDN:
<!-- Latest patch release -->
<script src="https://cdn.auth0.com/js/auth0/9.32.0/auth0.min.js"></script>
From npm:
npm install auth0-js
After installing the auth0-js module using npm, you'll need to bundle it up along with all of its dependencies, or import it using:
import auth0 from 'auth0-js';
Provides support for all the authentication flows.
var auth0 = new auth0.WebAuth({
domain: '{YOUR_AUTH0_DOMAIN}',
clientID: '{YOUR_AUTH0_CLIENT_ID}'
});
Provides an API client for the Auth0 Authentication API.
var auth0 = new auth0.Authentication({
domain: '{YOUR_AUTH0_DOMAIN}',
clientID: '{YOUR_AUTH0_CLIENT_ID}'
});
Provides an API Client for the Auth0 Management API (only methods meant to be used from the client with the user token). You should use an access_token with the https://YOUR_DOMAIN.auth0.com/api/v2/ audience to make this work. For more information, read the user management section of the Auth0.js documentation.
var auth0 = new auth0.Management({
domain: '{YOUR_AUTH0_DOMAIN}',
token: '{ACCESS_TOKEN_FROM_THE_USER}'
});
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
To provide feedback or report a bug, please raise an issue on our issue tracker.
Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?
This project is licensed under the MIT license. See the LICENSE file for more info.