# What This Is {% hint style="info" %} Stuck? Reach out on [Discord](https://discord.gg/mJdYJSdcm4). We’ll help you debug it. {% endhint %} oidc-spa is an OpenID Connect client for browser-first web apps. It implements the [Authorization Code Flow with PKCE](https://docs.oidc-spa.dev/resources/why-no-client-secret) and supports [DPoP](https://docs.oidc-spa.dev/security-features/dpop). It also ships [token validation utilities for JavaScript backends](https://docs.oidc-spa.dev/integration-guides/backend-token-validation). It includes [security defenses](https://docs.oidc-spa.dev/security-features/overview) to reduce token exposure risks in the browser. It’s one [dependency-free](https://npmgraph.js.org/?q=oidc-spa) library for the full stack. It can replace frontend SDKs like `keycloak-js`, `MSAL.js`, or `@auth0/auth0-spa-js`. It can also replace backend token tooling like `jsonwebtoken`, `jose`, or `express-jwt`. **Why we built it** Most OIDC client libraries handle the basic sign-in flow well. But they leave you to implement: * Token renewal, and what happens on expiry. * Idle timeout UX. Auto-logout and re-auth prompts. * Login/logout sync across tabs. * Reliable session restore on reload, including third‑party cookie blocks. * Provider quirks. Keycloak, Entra ID, and Auth0 differ in practice. We also wanted a TanStack-style developer experience: * Types flowing from config into the runtime API. * APIs that are hard to misuse. * Mockable OIDC for tests and “no-auth” / degraded environments. So we built `oidc-spa`. It’s opinionated and high-level. It has few knobs by design. It gives you enterprise-grade auth out of the box. So you can focus on your app. ## Dive In Ready to integrate? Start here. {% content-ref url="integration-guides/example-setups" %} [example-setups](https://docs.oidc-spa.dev/integration-guides/example-setups) {% endcontent-ref %} ## Positioning Here’s where oidc-spa sits compared to server-side OIDC:
| Browser-Side OIDC | Server-Side OIDC | |
|---|---|---|
| Implementation | oidc-spa, keycloak-js, angular-oauth2-oidc, react-oidc-context, @auth0/auth0-spa-js, @azure/msal-browser, @axa-fr/oidc-client, oidc-client-ts (without client secret) | nuxt-oidc-auth, oidc-client-ts (with client secret), NextAuth/Auth.js/BetterAuth (often “roll your own auth” frameworks that can broker OIDC providers) |
| OIDC Model | The frontend is the OIDC client. Your backend API is an OAuth resource server. The frontend calls the API with an access token. The API can validate the token signature and resolve identity offline. | The backend is the OIDC client. User identity is tracked with session cookies. In this model, there is usually no OAuth resource server. Access tokens are mainly used for calling third-party APIs. |
| Infrastructure Requirement | None. The browser talks directly to the authorization server. | Requires a stateful backend and a shared session store (e.g. Redis). |
| Setup | Simple. Auth is decoupled from your app framework, router, and API. | Tightly coupled to a framework. You typically build login/logout routes and middleware. |
| Security | Historically weaker because tokens exist in the browser. With DPoP and modern defenses, the security gap can shrink significantly. See details. | Secure by design. Tokens are not exposed to frontend code. |
| Server-side rendering | Limited. The server renders without user context. Auth-aware UI renders on the client. See in practice. | Seamless. The server knows who the user is during render. However, it comes with performance implications if not finely tuned. |
| Support | Keycloak, Microsoft Entra ID, Auth0, Ory Hydra, and most well-established platforms/systems support public OIDC clients seamlessly. Other providers like Clerk, WorkOS, or Dex still don't fully support public clients. | Supporting the Authorization Code flow with a client secret is the baseline expectation for every OIDC provider. |