oidc-client is the legacy JavaScript library for browser-based OIDC authentication, now deprecated in favor of oidc-client-ts. oidc-client-ts is the modern TypeScript rewrite that serves as the core standard for Single Page Applications (SPAs). openid-client is a specialized library designed for Node.js backends and confidential clients, not browsers. react-oidc-context is a React-specific wrapper that simplifies integrating oidc-client-ts using hooks and context providers.
Implementing authentication in modern web applications requires careful selection of tools that match your runtime environment and framework. The oidc-client ecosystem has evolved significantly, shifting from legacy JavaScript to modern TypeScript, while distinct libraries serve backend versus frontend needs. Let's compare how these four packages handle authentication flows, environment constraints, and framework integration.
oidc-client was the original standard for browser-based OIDC.
// oidc-client: Legacy setup (Do Not Use)
const userManager = new Oidc.UserManager({
authority: "https://accounts.google.com",
client_id: "your-client-id",
redirect_uri: "http://localhost:3000/callback"
});
oidc-client-ts is the direct successor and rewrite.
// oidc-client-ts: Modern setup
import { UserManager } from "oidc-client-ts";
const userManager = new UserManager({
authority: "https://accounts.google.com",
client_id: "your-client-id",
redirect_uri: "http://localhost:3000/callback"
});
openid-client targets server-side environments.
// openid-client: Backend setup
import { customFetch, Issuer } from "openid-client";
const issuer = await Issuer.discover("https://accounts.google.com");
const client = new issuer.Client({
client_id: "your-client-id",
client_secret: "your-client-secret" // Secure on server
});
react-oidc-context wraps the browser client for React.
oidc-client-ts.// react-oidc-context: React setup
import { AuthProvider } from "react-oidc-context";
const config = {
authority: "https://accounts.google.com",
client_id: "your-client-id",
redirect_uri: "http://localhost:3000/callback"
};
// Wrap your app
<AuthProvider {...config}>...</AuthProvider>
Security boundaries define which library you can safely use. Browser-based apps are "public clients" and cannot store secrets. Server apps are "confidential clients" and should.
oidc-client-ts enforces public client security.
// oidc-client-ts: PKCE handled automatically
await userManager.signinRedirect();
// No client_secret in config
openid-client supports confidential client flows.
client_secret_basic or client_secret_post.// openid-client: Using client secret
const tokenSet = await client.callback(redirectUri, params, {
code_verifier: "verifier",
state: "state"
});
// Secret used internally during token exchange
react-oidc-context inherits oidc-client-ts security.
// react-oidc-context: Secure hook usage
const { isAuthenticated, signoutRedirect } = useAuth();
// PKCE and token handling abstracted away
oidc-client had legacy security models.
// oidc-client: Legacy security (Risky)
// No type safety to prevent misconfiguration
userManager.signinRedirect();
Managing the user session lifecycle is a core task. Each library exposes this differently.
oidc-client-ts gives manual control over the user manager.
// oidc-client-ts: Manual user retrieval
const user = await userManager.getUser();
if (user?.access_token) {
// Attach token to API calls
}
react-oidc-context automates state via hooks.
useAuth hook provides reactive user state.// react-oidc-context: Reactive state
const { user, isLoading } = useAuth();
if (isLoading) return <div>Loading...</div>;
return <div>Hello {user?.profile.name}</div>;
openid-client manages sessions on the server.
// openid-client: Token validation
const claims = await client.userinfo(tokenSet.access_token);
// Validate claims on server side
oidc-client used older event patterns.
// oidc-client: Legacy events
userManager.events.addUserLoaded((user) => {
console.log("User loaded", user);
});
The amount of code you write depends on how much the library abstracts for your specific framework.
react-oidc-context is purpose-built for React.
// react-oidc-context: Protected Route
function ProtectedRoute() {
const { isAuthenticated } = useAuth();
return isAuthenticated ? <Dashboard /> : <Login />;
}
oidc-client-ts requires manual React integration.
// oidc-client-ts: Custom React Hook
function useUserManager() {
const [user, setUser] = useState(null);
// Manual wiring of userManager events required
return user;
}
openid-client integrates with Express or NestJS.
// openid-client: Express Middleware
app.get("/profile", async (req, res) => {
const tokens = req.session.tokens;
const userinfo = await client.userinfo(tokens.access_token);
res.json(userinfo);
});
oidc-client requires legacy integration patterns.
// oidc-client: Callback pattern
userManager.signinRedirectCallback().then(function (user) {
// Handle success
}).catch(function (err) {
// Handle error
});
| Feature | oidc-client-ts | react-oidc-context | openid-client | oidc-client |
|---|---|---|---|---|
| Environment | Browser (SPA) | Browser (React) | Node.js (Backend) | Browser (Legacy) |
| Language | TypeScript | TypeScript | TypeScript/JS | JavaScript |
| Client Type | Public (PKCE) | Public (PKCE) | Confidential (Secret) | Public (PKCE) |
| Integration | Manual / Custom | React Hooks | Server Middleware | Manual / Legacy |
| Status | β Active | β Active | β Active | β Deprecated |
oidc-client-ts is the foundation ποΈ for any browser-based authentication. Use it directly if you are not using React or need maximum control over the authentication lifecycle.
react-oidc-context is the accelerator π for React teams. It removes the boilerplate of wiring up oidc-client-ts manually, letting you focus on building UI components rather than auth logic.
openid-client is the secure vault π for your backend. Use it when you need to keep tokens off the client entirely (BFF pattern) or when your backend needs to call other APIs on behalf of the user.
oidc-client is the legacy system πΈοΈ. Do not start new projects with it. If you are still using it, treat migration to oidc-client-ts as a security priority.
Final Thought: Security and environment are your primary decision factors. If you are in the browser, use oidc-client-ts (or its React wrapper). If you are on the server, use openid-client. Never mix confidential client secrets into browser-based libraries.
Avoid this package for any new development. It is officially deprecated and no longer receives security updates or bug fixes. If you are maintaining a legacy system using this, plan a migration to oidc-client-ts immediately to ensure security compliance.
Choose oidc-client-ts if you are building a vanilla JavaScript or TypeScript Single Page Application (SPA) without a specific framework wrapper. It provides the core OIDC protocol implementation, token management, and silent renew features for public clients running in the browser.
Choose openid-client if you are implementing authentication on a Node.js backend or a confidential client where you can safely store a client secret. It is not suitable for browser-based SPAs due to security risks associated with exposing secrets in client-side code.
Choose react-oidc-context if you are building a React application and want a streamlined integration. It wraps oidc-client-ts to provide easy-to-use hooks like useAuth and context providers, reducing the boilerplate required to manage user sessions and authentication state.
Library to provide OpenID Connect (OIDC) and OAuth2 protocol support for client-side, browser-based JavaScript client applications. Also included is support for user session and access token management.
Node.js v4.4 or later required.
npm install oidc-client --save
NOTE: if you're not already using babel-polyfill make sure you run
npm install --save babel-polyfill as well. Then include it in your build.
If you don't use a package manager or a module loader, then you can get the library from the dist folder on github here.
If you intend to use this library directly in a browser and are not using UMD/AMD then there is a compiled version in the ~/dist folder. It is already bundled/minified and contains the necessary dependencies and polyfills (mainly for ES6 features such as Promises).
If you are using UMD/AMD and/or you already have included an ES6 polyfill (such as babel-polyfill.js) then you can include the UMD packaged version of the file from the ~/lib folder.
git clone https://github.com/IdentityModel/oidc-client-js.git
cd oidc-client-js
npm install
npm run build
npm start
and then browse to http://localhost:15000.
npm test
Some initial docs are here.
All are welcome on the issue tracker.