Library / SDK
authts/react-oidc-context avatar
authts/react-oidc-context

react-oidc-context: OIDC login state for a React SPA through one provider

Lightweight auth library based on oidc-client-ts for React single page applications (SPA). Support for hooks and higher-order components (HOC).

1,035 stars95 forksTypeScriptMIT

At a glance

What is it?
react-oidc-context is a MIT licensed React wrapper around oidc-client-ts that puts the User and UserManager into a context, intercepts the auth redirect itself, and exposes both hooks and higher-order components. The hard part is not the login, it is the onSigninCallback requirement that clears the URL payload.
Who is it for?
react-oidc-context is a sensible pick for a React single page application that needs plain OpenID Connect and wants the redirect interception and token state handled for it, and the MIT licence keeps it easy to adopt commercially; it is the wrong pick if you need a framework-agnostic SDK, a non-OIDC flow such as plain OAuth2 client credentials, or a library whose configuration is decoupled from oidc-client-ts, and before you integrate you should confirm that your identity provider supports silent renew with the redirect_uri you register, because the library relies on automatic silent renew and on you clearing the callback payload yourself.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 132 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One provider holds the User and the UserManager

react-oidc-context is described as a lightweight auth library for React single page applications, built on top of oidc-client-ts. The distinction matters: this project does not implement the OpenID Connect protocol itself, it wraps a library that does and adds the React binding.

What the binding provides is context. The `User` object and the `UserManager` are held in the React context, so any component below the provider can reach them. The package description is explicit about the design: OpenID Connect and OAuth2 authentication using the react context api as state management.

Two more things happen automatically. The library intercepts the auth redirects by looking at the query and fragment parameters and acts accordingly, so the callback landing on your application is handled without you writing that route yourself. You still have to set up a redirect uri pointing at your application, but you do not need to create the route for it. And token renewal is available through the automatic silent renew feature of the underlying library.

The library supports two consumption styles, hooks and higher-order components, so a codebase with class components and one built entirely on function components can both use it without a rewrite.

Installing the pair and wrapping the app in AuthProvider

The package has a peer dependency on oidc-client-ts, so both are installed together. With npm:

bash
npm install oidc-client-ts react-oidc-context --save

With yarn:

bash
yarn add oidc-client-ts react-oidc-context

Configuration happens by wrapping the application in `AuthProvider` and spreading the OIDC configuration into it:

jsx
import { AuthProvider } from "react-oidc-context";

const oidcConfig = {
  authority: "<your authority>",
  client_id: "<your client id>",
  redirect_uri: "<your redirect uri>",
  // ...
};

ReactDOM.render(
  <AuthProvider {...oidcConfig}>
    <App />
  </AuthProvider>,
  document.getElementById("app")
);

The configuration is described as tightly coupled to oidc-client-ts, which is a design decision with consequences. It means there is one configuration schema to learn rather than two, and it means anything oidc-client-ts supports is available here. It also means there is no way to swap the underlying library out without rewriting the integration, so a project that outgrows this one will not find a pluggable seam.

The useAuth hook and the redirect that must be cleared

Inside the tree, `useAuth` returns the state and the methods. The state is `isLoading`, `isAuthenticated` and `user`; the methods are `signinRedirect`, `removeUser` and `signOutRedirect`.

jsx
function App() {
    const auth = useAuth();

    switch (auth.activeNavigator) {
        case "signinSilent":
            return <div>Signing you in...</div>;
        case "signoutRedirect":
            return <div>Signing you out...</div>;
    }

    if (auth.isLoading) {
        return <div>Loading...</div>;
    }

    if (auth.isAuthenticated) {
        return <div>Hello {auth.user?.profile.sub}</div>;
    }

    return <button onClick={() => void auth.signinRedirect()}>Log in</button>;
}

The `activeNavigator` property tells you which redirect is in flight, which is how you render a signing in or signing out state rather than a blank screen. The `error` property is also exposed, and the sample renders the error source and message.

Now the part that catches people out. The project states that you must provide an implementation of `onSigninCallback` in `oidcConfig` to remove the payload from the URL upon successful login. Without it, a page refresh leaves the payload in the URL, and `signinSilent`, which handles renewing the token, stops working. A working implementation is provided in the source, and the guidance is to copy it rather than write your own from scratch.

withAuth for class components and withAuthenticationRequired for routes

Not every React codebase is hooks-only, so the package ships `withAuth`, a higher-order component that adds the `auth` property to a class component. The wrapped component receives exactly the same properties as the hook returns:

jsx
import { withAuth } from "react-oidc-context";

class Profile extends React.Component {
    render() {
        const auth = this.props.auth;
        return <div>Hello {auth.user?.profile.sub}</div>;
    }
}

export default withAuth(Profile);

Route protection is the other higher-order component, `withAuthenticationRequired`. Wrapping a route component in it means an unauthenticated visitor is redirected to the login page instead of seeing the protected content:

jsx
import { withAuthenticationRequired } from "react-oidc-context";

const PrivateRoute = () => (<div>Private</div>);

export default withAuthenticationRequired(PrivateRoute, {
  OnRedirecting: () => (<div>Redirecting to the login page...</div>)
});

The second argument is options, and the example uses `OnRedirecting` to render a message while the redirect is happening. That is a small detail with a real consequence: without it, the user sees a blank frame during the redirect, and on a slow identity provider that gap is long enough to look like a crash. Worth wiring up in any application you ship.

Reading the access token from outside the provider

Inside the provider tree, calling a protected API is straightforward. The access token comes off the user object and goes into the Authorization header:

jsx
const token = auth.user?.access_token;
const response = await fetch("https://api.example.com/posts", {
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

Outside the tree it is harder, and this is where the library's own documentation gets specific. A Redux slice, for example, is not a child of `AuthProvider`, so it cannot use the hook. The documented workaround is to read the user directly from local storage, where the library keeps it under a key built from the authority and the client id:

jsx
import { User } from "oidc-client-ts"

function getUser() {
    const oidcStorage = localStorage.getItem(`oidc.user:<your authority>:<your client id>`)
    if (!oidcStorage) {
        return null;
    }

    return User.fromStorageString(oidcStorage);
}

This is honest and useful, but it is also the sharp edge of the design. The storage key format is an internal detail of oidc-client-ts, and the workaround depends on local storage being where the user was persisted, which the text ties to the `WebStorageStateStore`. A team that reconfigures state storage has to update this code too, and there is no abstraction in between.

Peer dependency ranges and the shape of the package

The published package declares two peer dependencies, and they define the compatibility envelope. `oidc-client-ts` must satisfy `^3.1.0`, and `react` must be `>=16.14.0`. The React floor of 16.14 sits above the release that introduced hooks, which is a sensible line for a library whose primary API is a hook.

The build is TypeScript throughout. The build script runs a custom build script and then a separate type build, `tsc --emitDeclarationOnly` followed by `api-extractor run`, which is the tool that rolls up the type declarations into the single public `.d.ts` file listed in the exports map. The package also ships a UMD build at dist/umd/react-oidc-context.js, an ESM build, and a CommonJS fallback, with the root export mapping each.

Quality tooling is conventional for a TypeScript library of this size: Jest for tests, ESLint run with `--max-warnings=0`, husky for git hooks, and an example directory with its own package.json and index.tsx. The `files` field restricts the published tarball to `dist`, so the repository's test and example trees never reach npm.

Maintenance status, licensing, and the upgrade path

The repository is not archived, and the last push was on 2026-06-12. The release history shows three versions in the recent past: v3.3.1 on 2026-03-13, v3.3.0 on 2025-03-27, and v3.2.0 on 2024-10-04. The gap between v3.2.0 and v3.3.0 is about six months, and the gap between v3.3.0 and v3.3.1 is close to a year, so this is a project that ships on a slow cadence rather than a fast-moving one. There is no statement in the README about a support policy for older major versions.

Licensing is the easy part. The package is MIT licensed, which is permissive enough for commercial use without the copyleft obligations that would apply to a stronger copyleft licence, and the LICENSE file sits at the repository root. Since the library depends on oidc-client-ts, which is a separate package with its own terms, a compliance review has two lines to check rather than one.

The upgrade cost for a project already using this library is the question of what changes between minor versions in a context provider, since a change in how the redirect is handled or how state is exposed would ripple through every consumer. The repository has a docs/ directory, an api-extractor configuration and a scripts/ directory, so the public API surface is deliberately controlled, but the README does not include a migration or upgrade guide, so version bumps need reading rather than applying.

Editorial conclusion

react-oidc-context is a sensible pick for a React single page application that needs plain OpenID Connect and wants the redirect interception and token state handled for it, and the MIT licence keeps it easy to adopt commercially; it is the wrong pick if you need a framework-agnostic SDK, a non-OIDC flow such as plain OAuth2 client credentials, or a library whose configuration is decoupled from oidc-client-ts, and before you integrate you should confirm that your identity provider supports silent renew with the redirect_uri you register, because the library relies on automatic silent renew and on you clearing the callback payload yourself.

Frequently asked questions

How do I install react-oidc-context?

Install both packages, since react-oidc-context has a peer dependency on oidc-client-ts: npm install oidc-client-ts react-oidc-context --save, or yarn add oidc-client-ts react-oidc-context.

Why does signinSilent stop working after a page refresh?

Because the callback payload is still in the URL. The project states that you must provide an implementation of onSigninCallback in the config to remove the payload upon successful login, otherwise a refresh leaves it there and signinSilent, which renews the token, will not work. A working implementation is provided in the source.

How do I protect a route in react-oidc-context?

Wrap the route component in the withAuthenticationRequired higher-order component. An unauthenticated visitor is then redirected to the login page, and you can pass an OnRedirecting option to render a message during that redirect.

Can I use react-oidc-context with class components?

Yes. The withAuth higher-order component adds an auth property to a class component, and that property has the same properties as the useAuth hook returns.

How do I get the access token outside the AuthProvider tree?

Read the stored user from local storage using the key oidc.user:<your authority>:<your client id> and convert it with User.fromStorageString from oidc-client-ts. The documentation presents this for cases such as a Redux slice that is not a child of the provider.

Official sources

  1. authts/react-oidc-context on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/authts-react-oidc-context.svg)](https://hysenlabs.com/projects/authts-react-oidc-context)

Was this useful?