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-legacyinstead ofprimus-angular-ui. The@primus/ui-coresetup 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​
| Layer | Package | What it provides |
|---|---|---|
| Base design system | @primus/ui-core | Design tokens, semantic HTML styles, Web Components, toast API |
| Angular components | primus-angular-ui | 50+ Angular components for SaaS apps |
| Angular legacy | primus-angular-ui-legacy | Same 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?​
Use Standalone (recommended for Angular 17+)​
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​
| Standalone | NgModule | |
|---|---|---|
| Angular version | 17+ (recommended) | 14+ (supported) |
| Bootstrap | bootstrapApplication() | platformBrowserDynamic().bootstrapModule() |
| Primus setup | providePrimus() | PrimusUiModule.forRoot() |
| Tree-shaking | Better — per-component | Module-level |
| New projects | ✅ Use this | Use only if migrating |