Angular Better Auth Wrapper
ngx-better-auth is an Angular 20+ wrapper library designed to integrate with the Better Auth authentication system. It provides a reactive approach to session management, leveraging Angular's signal primitives for real-time session status (`session`, `isLoggedIn`). The library offers a clean dependency injection setup using observables and includes modern Angular guards (`canActivate`, `hasRole`) for route protection, ensuring a streamlined development experience for authentication flows. Currently at version `0.10.3`, it maintains a regular release cadence with frequent bug fixes and feature enhancements, closely tracking Angular and better-auth major versions. Its key differentiator is the direct integration with Better Auth's plugin ecosystem and a focus on leveraging modern Angular features like signals for session state.
Common errors
-
NG0900: Error: NG0900: 'provideBetterAuth' is not a function
cause Attempting to use `provideBetterAuth` with an Angular version older than 14 (when `ApplicationConfig` and functional providers were introduced) or with an incorrect import.fixEnsure your Angular project is at least version 14 (preferably 20+ for full compatibility) and that `provideBetterAuth` is imported correctly from `ngx-better-auth` in `app.config.ts`. -
Error: Can't resolve all parameters for AuthService (?). This typically indicates that it's used in a context where dependency injection is not available.
cause Attempting to inject `AuthService` in a non-DI context, or without `provideBetterAuth` being correctly configured in the application's providers.fixEnsure `AuthService` is injected within an Angular component, service, or directive constructor. Verify that `provideBetterAuth` is included in the `providers` array of your `ApplicationConfig` or module. -
Error: Peer dependency '@angular/core@^16.0.0' not installed.
cause The installed Angular version does not meet the `ngx-better-auth` peer dependency requirement, which is `>=20.0.0`.fixUpgrade your Angular project to version 20 or higher using `ng update @angular/core @angular/cli --allow-dirty`. -
Property 'session' does not exist on type 'AuthService'.
cause Attempting to access `session` as an observable or direct property instead of a signal, or using an outdated version of `ngx-better-auth` that did not yet use signals.fixAccess `session` as a signal: `this.authService.session()`. Ensure you are on a version of `ngx-better-auth` that supports signals (e.g., v0.1.0+ for initial signal integration, later versions for expanded use).
Warnings
- breaking Starting from v0.8.0, the library explicitly removed its own type definitions and now relies on types directly from the `better-auth` package. This requires ensuring `better-auth` is correctly installed and its types are available.
- gotcha The `hasRole` guard in v0.10.2 and earlier had issues with comma-separated role strings, potentially leading to incorrect authorization decisions.
- gotcha Social sign-in parameters and default `callbackURL` have seen fixes in versions prior to v0.8.3 and v0.8.2 respectively. Older versions might experience issues with social login flows.
- breaking The library is specifically designed for Angular 20+. Using it with older Angular versions will result in peer dependency errors and runtime failures.
- gotcha Incorrect configuration of the `baseURL` or `basePath` in `provideBetterAuth` can lead to authentication requests failing with network errors or 404s, as the client won't know where to send requests.
Install
-
npm install ngx-better-auth -
yarn add ngx-better-auth -
pnpm add ngx-better-auth
Imports
- AuthService
const AuthService = require('ngx-better-auth').AuthServiceimport { AuthService } from 'ngx-better-auth' - provideBetterAuth
import { provideAuth } from 'ngx-better-auth'import { provideBetterAuth } from 'ngx-better-auth' - canActivate
import { AuthGuard } from 'ngx-better-auth'import { canActivate, redirectUnauthorizedTo } from 'ngx-better-auth' - UsernameService
import { UsernameService } from 'ngx-better-auth'
Quickstart
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideBetterAuth } from 'ngx-better-auth';
import { environment } from './environments/environment';
import { usernameClient, twoFactorClient, adminClient } from 'better-auth/client/plugins';
import { routes } from './app.routes';
import { AuthService } from 'ngx-better-auth';
import { Component, inject } from '@angular/core';
const accessControl = { /* ... your access control setup ... */ };
const admin = ['admin'];
const moderator = ['moderator'];
const user = ['user'];
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideBetterAuth({
baseURL: environment.apiUrl,
basePath: '/auth',
plugins: [
usernameClient(),
twoFactorClient({
onTwoFactorRedirect: () => {
window.location.href = '/two-factor-auth';
},
}),
adminClient({
ac: accessControl,
roles: {
admin,
moderator,
user
}
})
]
})
]
};
// Example component usage
@Component({
selector: 'app-root',
standalone: true,
template: `
<h1>Welcome, {{ userName() ?? 'Guest' }}</h1>
<p>Logged In: {{ isLoggedIn() }}</p>
<button *ngIf="!isLoggedIn()" (click)="signIn()">Sign In</button>
<button *ngIf="isLoggedIn()" (click)="signOut()">Sign Out</button>
`
})
export class AppComponent {
private readonly authService = inject(AuthService);
isLoggedIn = this.authService.isLoggedIn;
userName = () => this.authService.session()?.user?.name ?? 'Loading...';
signIn() { /* ... implementation for sign-in ... */ }
signOut() {
this.authService.signOut();
}
}