keycloak-angular wraps keycloak-js in Angular providers, signals and guards
Easy Keycloak integration for Angular applications.
At a glance
- What is it?
- keycloak-angular is a community library that makes keycloak-js usable inside an Angular application without writing the wiring yourself, providing a provider function, HTTP interceptors, route guard factories, a roles directive and a signal carrying Keycloak events. Its main constraint is also its main warning, since the library version has to track the Angular major version exactly.
- Who is it for?
- keycloak-angular fits an Angular team that has already chosen Keycloak and wants the client wired into the framework rather than beside it, especially one on a recent Angular major where the library is actively supported. Skip it if you cannot upgrade keycloak-js alongside it, because the client version range and the server version need to line up, or if your application is not Angular at all.
- 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 24 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Keycloak-js without the wrapper code
The project describes itself as easy Keycloak integration for Angular applications, and the README is precise about what it wraps. It is a library that makes it easier to use keycloak-js in Angular applications, and keycloak-js is the official JavaScript adapter for Keycloak.
The reason a wrapper exists at all is that the raw client is framework agnostic. It knows how to talk to a Keycloak server, how to parse tokens and how to refresh them, and it knows nothing about Angular's dependency injection, its HTTP stack or its router. A team that uses it directly ends up writing the same glue in every application, and that glue is where the bugs live.
The feature list in the README is that glue, itemised. There is easy initialization through a `provideKeycloak` function combined with `provideAppInitializer`. The client can be injected directly into components, services and other parts of the app, with no custom wrapper service needed. There are HTTP interceptors that add the bearer token to the `Authorization` header, modular and configurable through injection tokens, with helper functions for writing your own. Keycloak events are exposed as Angular Signals through the `KEYCLOAK_EVENT_SIGNAL` injection token. There is automatic token refresh through `withAutoRefreshToken`, which considers user activity and a session timeout. There are route guards built with the `createAuthGuard` factory for `CanActivate` and `CanActivateChild`. And there is a `*kaHasRoles` structural directive that shows or hides parts of the DOM based on the user's resource or realm roles.
The licence is MIT, the primary language is TypeScript, and the library is published to npm as `keycloak-angular`.
provideKeycloak and the initializer
The setup path is short enough to read in full, and the shape of the configuration tells you how the library fits into Angular's startup model.
import { provideKeycloak } from 'keycloak-angular';The provider is added to the `providers` array of the `ApplicationConfig` object, which the README places in `app.config.ts`, and it takes a config block with the server URL, the realm and the client id, plus an optional `initOptions` block.
provideKeycloak({
config: {
url: 'keycloak-server-url',
realm: 'realm-id',
clientId: 'client-id'
},
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'
}
}),The important detail is what happens when `initOptions` is present. The README states that the library then uses `provideAppInitializer` automatically, so the developer does not need to call it, and that initialization follows the recommended approach for starting dependencies.
The three notes under that example cover the variations. If you need to control when `keycloak.init` is called, do not pass `initOptions` to `provideKeycloak`, and calling `keycloak.init` manually becomes your responsibility. And the README points out that Angular's `APP_INITIALIZER` is deprecated, with `provideAppInitializer` being the recommended replacement.
That last point is the kind of thing that separates a maintained wrapper from an abandoned one. The library is following Angular's own migration path rather than asking users to keep a deprecated token alive.
The silent check-sso iframe needs a file served by your app
The `check-sso` option in that configuration is worth understanding, because it is the difference between a user seeing the application and seeing a login page.
The README explains that with a silent `check-sso` enabled, the browser avoids a full redirect to the Keycloak server and back to the application, and the action is performed in a hidden iframe. The effect is that the application resources are loaded and parsed only once during initialization rather than being reloaded after a redirect.
The cost of that is a requirement on your own application. To enable communication through the iframe, you have to serve a static HTML file from your application at the location specified in `silentCheckSsoRedirectUri`, and the README says to create a file named `silent-check-sso.html` in the `public` or `assets` directory and paste in this content.
<html>
<body>
<script>
parent.postMessage(location.href, location.origin);
</script>
</body>
</html>That file does one thing, and it does it in one line. It posts the current location back to the parent window with the origin as the target, which is the handshake the Keycloak client uses to read the result of the silent check.
Two practical notes follow. The path has to match exactly what you put in `silentCheckSsoRedirectUri`, and the file has to be served rather than routed, because the iframe loads it as a document. Getting this wrong produces a silent check that never completes, and the symptom is a login redirect in an application that has a valid session, which is a confusing thing to debug.
For everything else about the client's options, the README points to the Keycloak JavaScript adapter documentation.
Interceptors, guards, signals and a structural directive
The remaining features divide into two groups, and the second group is where the Angular-specific value sits.
The token handling comes first. The built-in interceptors add the bearer token to the `Authorization` header, they are modular and configured through injection tokens, and the README notes you can create your own interceptors with provided helper functions. On top of that, `withAutoRefreshToken` handles refresh automatically, and the README is specific that it considers the user activity and a session timeout, which is the difference between a token that refreshes because someone is clicking and one that refreshes because the tab is open but idle.
The Angular integration comes second. `createAuthGuard` is a factory for building guards for `CanActivate` and `CanActivateChild`, and the README describes it as helping you secure routes with custom logic. The guard is created rather than injected, so the guard's own options are supplied at the call site, which is how you attach the conditions that your application needs rather than a single global rule.
The events signal is the third piece. Keycloak events are available through Angular Signals, provided through the `KEYCLOAK_EVENT_SIGNAL` injection token, so a component can read the current authentication state reactively instead of subscribing to the client by hand and cleaning up after itself.
The `*kaHasRoles` directive is the fourth. It shows or hides parts of the DOM based on the user's resource or realm roles, and being a structural directive it removes the element from the tree rather than hiding it with CSS, which matters when the condition is a security boundary rather than a presentation choice. The README draws that distinction by naming both resource roles and realm roles, since they come from different places in Keycloak and a directive that only reads one of them will be wrong half the time.
The version table is the real adoption decision
Before anything else, the table of supported versions.
| Angular | keycloak-js | keycloak-angular | Support |
| :-----: | :---------: | :--------------: | :-----------------: |
| 22.x | 18 - 26 | 22.x.x | New Features / Bugs |
| 21.x | 18 - 26 | 21.x.x | Bugs |
| 20.x | 18 - 26 | 20.x.x | - |
| 19.x | 18 - 26 | 19.x.x | - |Only the newest Angular line listed receives new features, the line below it receives bug fixes, and the older rows get nothing. The README gives the reason, and it is a good one: compiling Angular libraries can be incompatible between major versions, so a library that supported several majors at once would not really be supporting them.
The numbering was changed to make this readable. Starting with Angular v19, the library adopts the same major version numbering as Angular, so the version of keycloak-angular you need is visible from your Angular version, and the table lists older pairings for reference, with Angular 15 and 16 mapping to keycloak-angular 13.x.x and 14.x.x and correspondingly older keycloak-js ranges.
The keycloak-js column has a second rule behind it. The README notes that keycloak-js is a peer dependency, which is what allows you to choose the right client version for your project, and the Keycloak client documentation recommends using the same version as your Keycloak server installation. So there are two constraints to satisfy at once: the Angular major and the server version.
For a team on a recent Angular major this is a non-issue. For a team on an older one it means the library is effectively frozen, and the honest answer is that the choice is between upgrading Angular and maintaining an internal wrapper.
External configuration and the example projects
The library also supports initialising from a configuration file that is fetched at runtime, which is the pattern a multi-environment deployment usually needs.
const { config, initOptions } = await fetch('/config.json').then((res) => res?.json());The rest of the example builds an `ApplicationConfig` from those values and passes them to the provider, so the server URL, realm and client id can be changed without rebuilding the application.
The examples in the repository are set up to show that, and the npm scripts reveal how they run. There is a Docker compose stack for a local Keycloak, a mock server for the parts that talk to a server, and three example applications served in the browser.
"build": "ng build keycloak-angular --configuration production",
"test": "ng test keycloak-angular",
"lint": "ng lint && prettier -c .",
"typecheck": "tsc --noEmit"The example names in the `projects/` directory are the interesting part, because they map to the three ways an Angular application can be set up. There is an NgModule based example, a standalone example, and a fetch-config example for the external configuration path. The combined run scripts build the library and then start the pieces together with `concurrently`, one for the NgModule example and one that adds the mock server for the standalone example.
The `projects/` directory is where the example applications live, alongside `docs/`, an `angular.json` workspace file, a Prettier configuration, an ESLint configuration and a `.all-contributorsrc`. The scripts also include `typecheck` running `tsc --noEmit`, and linting that runs the Angular linter and then a Prettier check, so the repository holds itself to the same type and format checks it asks of its users.
A version-aligned library with a long support tail
The maintenance pattern is now visible, and it is a deliberate one.
The releases follow the Angular major lines. v20.1.0 and v21.0.0 were both published on 2025-12-31, and v22.0.0 on 2026-06-15, which is roughly the cadence of Angular's own major releases. The repository is not archived, and the last push was on 2026-09-28.
The version alignment means the library's release calendar is dictated by Angular's. A new Angular major is not an opportunity for the library to add features independently, it is a requirement to ship a new major of the library, and that is why the README frames the support column as a promise about which line gets what.
The consequence for an adopter is that the upgrade path of your framework is the upgrade path of this library. That is a cost when you are on an old major, since the old line stops receiving fixes, and it is a benefit when you are on a current one, since the library moves with you rather than lagging behind.
The licence is MIT, the README carries badges for the build status, known vulnerabilities and the npm version, and the repository includes a `CONTRIBUTING.md`, a `SPONSORS.md` and an `.all-contributorsrc` file. The vulnerability badge in particular is the one to keep an eye on, since a library that sits in the path of every authenticated request in an application inherits the urgency of any flaw in the token handling it wraps.
Editorial conclusion
keycloak-angular fits an Angular team that has already chosen Keycloak and wants the client wired into the framework rather than beside it, especially one on a recent Angular major where the library is actively supported. Skip it if you cannot upgrade keycloak-js alongside it, because the client version range and the server version need to line up, or if your application is not Angular at all. Verify first which keycloak-angular major matches your Angular version, which keycloak-js version your Keycloak server expects, and that the silent check-sso static file is actually served at the path you configured.
Frequently asked questions
How do I install keycloak-angular?
The README gives one command, `npm install keycloak-angular keycloak-js`. The `keycloak-js` package is a peer dependency of `keycloak-angular`, so you install it explicitly and choose the version that matches your Keycloak server.
Which version of keycloak-angular should I use for my Angular release?
Since Angular v19 the library uses the same major version number as Angular, so Angular 22 pairs with keycloak-angular 22.x.x. The README's support table says only the newest Angular line listed receives new features and bug fixes, and that Angular library compilation can be incompatible between major versions.
What does provideKeycloak do and do I need provideAppInitializer?
You add `provideKeycloak` to the providers array of the ApplicationConfig with the server URL, realm, client id and optional initOptions. The README states that when `initOptions` is provided the library uses `provideAppInitializer` automatically, and that if you omit `initOptions` you are responsible for calling `keycloak.init` yourself.
Why does the silent check-sso option need a static HTML file?
The silent check runs in a hidden iframe, so your application has to serve a document at the path given in `silentCheckSsoRedirectUri`. The README says to create `silent-check-sso.html` in the `public` or `assets` directory with a script that posts the location back to the parent window using the origin as the target.
How do I read Keycloak events and protect routes in keycloak-angular?
Keycloak events are exposed as Angular Signals through the `KEYCLOAK_EVENT_SIGNAL` injection token, and route guards are built with the `createAuthGuard` factory for `CanActivate` and `CanActivateChild`. There is also a `*kaHasRoles` directive that shows or hides DOM based on the user's resource or realm roles.
Official sources
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.
[](https://hysenlabs.com/projects/mauriciovigolo-keycloak-angular)Was this useful?