Skip to main content

Angular Setup

Complete setup guide for using Primus UI in an Angular application — including @primus/ui-core as the base design system.

1. Install packages​

npm install primus-angular-ui @primus/ui-core

Angular 16–20? Use primus-angular-ui-legacy instead of primus-angular-ui. The @primus/ui-core setup is identical.

2. Add styles to angular.json​

In your angular.json, add @primus/ui-core first in the styles array:

"styles": [
"node_modules/@primus/ui-core/dist/primus-ui.min.css",
"src/styles.scss"
]

PrimusThemeService from primus-angular-ui automatically bridges its --primus-* tokens to @primus/ui-core's --primary, --background, etc. tokens — no extra configuration needed.

3. Import the module​

NgModule setup:

import { PrimusUiModule } from 'primus-angular-ui';

@NgModule({
imports: [
PrimusUiModule.forRoot({
apiBaseUrl: 'https://api.yourdomain.com',
authToken: () => localStorage.getItem('primus_token')
})
]
})
export class AppModule {}

Standalone setup (Angular 17+):

import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { providePrimus, providePrimusTheme } from 'primus-angular-ui';

bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(),
providePrimus({
apiBaseUrl: 'https://api.yourdomain.com',
authToken: () => localStorage.getItem('primus_token')
}),
providePrimusTheme({ defaultTheme: 'dark' })
]
});

4. Use components​

Angular components from primus-angular-ui:

<primus-login
[showEmailLogin]="true"
[socialProviders]="['azure', 'auth0', 'google']"
(loggedIn)="onLogin($event)">
</primus-login>

<primus-data-table [columns]="columns" [data]="rows" [selectable]="true">
</primus-data-table>

<primus-stats-card label="Monthly Revenue" [value]="'$142k'" delta="+12%" trend="up">
</primus-stats-card>

Plain HTML elements — styled by @primus/ui-core automatically:

<!-- Buttons — no class needed for primary -->
<button>Save Changes</button>
<button data-variant="secondary">Cancel</button>
<button data-variant="danger">Delete</button>
<button class="outline">Export</button>

<!-- Badges -->
<span class="badge success">Active</span>
<span class="badge warning">Pending</span>
<span class="badge danger">Overdue</span>

<!-- Alert -->
<div role="alert" data-variant="success">Settings saved successfully.</div>
<div role="alert" data-variant="info">2 background jobs are running.</div>

<!-- Stat card -->
<div class="card stat">
<span class="card-label">Monthly Revenue</span>
<span class="card-value">$142,000</span>
<span class="card-delta up">+12%</span>
</div>

<!-- Table (auto-styled) -->
<div class="table">
<table>
<thead>
<tr><th>Tenant</th><th>Plan</th><th>Status</th></tr>
</thead>
<tbody>
<tr>
<td>Acme Corp</td>
<td>Enterprise</td>
<td><span class="badge success">Active</span></td>
</tr>
</tbody>
</table>
</div>

5. Theme switching​

PrimusThemeService controls both the Angular SDK and @primus/ui-core in one call:

import { PrimusThemeService } from 'primus-angular-ui';

@Component({ selector: 'app-root', template: `
<primus-theme-toggle></primus-theme-toggle>
` })
export class AppComponent {
constructor(private readonly themeService: PrimusThemeService) {}

toggleDark() {
this.themeService.toggleTheme();
// Updates --primus-* AND --primary/--background/--card etc. simultaneously
}
}

6. Add JS bundle (Web Components + Toast)​

For <primus-tabs>, <primus-dropdown>, and primus.toast():

"scripts": [
"node_modules/@primus/ui-core/dist/primus-ui.min.js"
]

Then in any component:

<!-- Tabs with underline variant -->
<primus-tabs>
<div role="tablist" class="underline">
<button role="tab">Overview</button>
<button role="tab">Settings</button>
</div>
<div role="tabpanel">Overview content</div>
<div role="tabpanel">Settings content</div>
</primus-tabs>
// Toast API
declare const primus: { toast: (msg: string, title?: string, opts?: object) => void };

primus.toast('Record saved.', 'Success', { variant: 'success', placement: 'bottom-right' });
primus.toast('Connection lost.', 'Error', { variant: 'danger' });

What's available​

LayerPackageWhat it provides
Base design system@primus/ui-coreDesign tokens, semantic HTML styles, Web Components, toast API
Angular componentsprimus-angular-ui50+ Angular components for SaaS apps
Angular legacyprimus-angular-ui-legacySame SDK for Angular 16–20

See the component list for the full catalog, or the @primus/ui-core reference for the base layer.


Standalone vs NgModule — which to use?​

Standalone is the default and recommended approach from Angular 17 onwards. It removes the need for NgModule boilerplate and tree-shakes unused components automatically.

// main.ts — Standalone bootstrap
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { providePrimus, providePrimusTheme } from 'primus-angular-ui';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
providers: [
provideRouter(routes),
provideHttpClient(),
providePrimus({ apiBaseUrl: 'https://api.yourdomain.com' }),
providePrimusTheme({ defaultTheme: 'dark' }),
],
});
// app.component.ts — Standalone component
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { PrimusSidebarComponent, PrimusHeaderComponent } from 'primus-angular-ui';

@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, PrimusSidebarComponent, PrimusHeaderComponent],
templateUrl: './app.component.html',
})
export class AppComponent {}

Use NgModule (Angular 16–21 projects that already use it)​

If your project already uses NgModule, keep it. Import PrimusUiModule in your root module:

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { PrimusUiModule } from 'primus-angular-ui';
import { AppComponent } from './app.component';

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule,
PrimusUiModule.forRoot({
apiBaseUrl: 'https://api.yourdomain.com',
authToken: () => localStorage.getItem('primus_token'),
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}

Quick comparison​

StandaloneNgModule
Angular version17+ (recommended)14+ (supported)
BootstrapbootstrapApplication()platformBrowserDynamic().bootstrapModule()
Primus setupprovidePrimus()PrimusUiModule.forRoot()
Tree-shakingBetter — per-componentModule-level
New projects✅ Use thisUse only if migrating