The official AdminLTE 4 port for Angular 22 — a signal-first, standalone-component library on Bootstrap 5.3. Dark mode, a config-driven sidebar, and a ⌘K command palette, all without jQuery or NgModules.
Standalone components, signal inputs (
input()/output()/model()), the new control flow (@if/@for/@switch), SSR-safe theming, and the modern esbuild application builder.
The same AdminLTE 4 dashboard, in the framework you know best — you're looking at the Angular edition:
Frameworks: Angular (you are here) · React · Next.js · Vue · Nuxt · Laravel · Django · AdminLTE core
🅰️ Angular 22, signal-first — standalone components,input()/output()/model(), the new control flow, zoneless-friendly.- 🌗 SSR-safe dark mode —
data-bs-themeon<html>, persisted tolocalStoragewith a system-preference fallback and a no-flash inline script. - 🧭 Config-driven sidebar — a typed
MenuNode[](headers, links, collapsible groups, badges, per-itemvisibleflags) with active-link detection and accordion treeviews. - ⌘ Command palette (⌘K) — fuzzy search over your menu with full keyboard navigation, routing through the Angular Router.
- 🧩 40+ components — layout, widgets and form controls, all with the
Lteprefix. - 📦 Tree-shakeable — standalone components, optional peer deps (ApexCharts, flatpickr, Tom Select, simple-datatables) lazy-loaded.
- 🎨 Bootstrap 5.3 — ships AdminLTE's compiled CSS via
@adminlte/angular/css.
npm install @adminlte/angular admin-lte bootstrap bootstrap-icons
# optional, for charts:
npm install apexcharts@adminlte/angular lists @angular/core, @angular/common, @angular/forms, @angular/router, bootstrap and admin-lte as peer dependencies.
In angular.json (or your global stylesheet):
Add this to your index.html <head> so the correct theme is applied before first paint:
<script>
(function () {
try {
var m = localStorage.getItem('lte-theme') || 'auto';
var d = m === 'dark' || (m === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.setAttribute('data-bs-theme', d ? 'dark' : 'light');
} catch (e) {}
})();
</script>(COLOR_MODE_NO_FLASH_SCRIPT is also exported from the library for SSR injection.)
Define a typed menu and drop the dashboard layout around your routed content:
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { DashboardLayoutComponent, type MenuNode } from '@adminlte/angular';
const MENU: MenuNode[] = [
{ type: 'header', text: 'MAIN NAVIGATION' },
{ type: 'item', text: 'Dashboard', route: '/', icon: 'bi-speedometer' },
{
type: 'group',
text: 'UI Elements',
icon: 'bi-collection',
children: [
{ type: 'item', text: 'Forms', route: '/forms', icon: 'bi-input-cursor-text' },
{ type: 'item', text: 'Tables', route: '/tables', icon: 'bi-table' },
],
},
{ type: 'item', text: 'Admin only', route: '/admin', icon: 'bi-lock', visible: false },
];
@Component({
selector: 'app-shell',
imports: [DashboardLayoutComponent, RouterOutlet],
template: `
<lte-dashboard-layout [menuItems]="menu" [currentPath]="currentPath()" [accordion]="true">
<router-outlet />
<span footer><b>Version</b> 4.0.0</span>
</lte-dashboard-layout>
`,
})
export class ShellComponent {
readonly menu = MENU;
readonly currentPath = signal('/'); // wire from Router NavigationEnd events
}Then build a page with the widgets:
<lte-app-content title="Dashboard" [breadcrumbs]="[{ label: 'Home', route: '/' }, { label: 'Dashboard' }]">
<div class="row">
<div class="col-lg-3 col-6">
<lte-small-box title="150" text="New Orders" icon="bi-bag" theme="primary" url="#" />
</div>
</div>
<lte-card title="Sales" icon="bi-bar-chart" [collapsible]="true" [maximizable]="true">
<lte-apex-chart [options]="chartOptions()" />
</lte-card>
</lte-app-content>Layout — LteDashboardLayout · LteAuthLayout · LteAppContent · LteTopbar · LteSidebar · LteSidebarBrand · LteSidebarNav · LteSidebarNavItem · LteSidebarOverlay · LteFooter · LteColorModeToggle · LteFullscreenToggle
Widgets — LteCard · LteSmallBox · LteInfoBox · LteAlert · LteCallout · LteProgress · LteProgressGroup · LteRatings · LteTimeline · LteProfileCard · LteDescriptionBlock · LteBreadcrumb · LteCommandPalette · LteApexChart · LteModal · LteDirectChat · LteTabs / LteTab · LteAccordion / LteAccordionItem · LteDatatable
Topbar dropdowns — LteNavMessages · LteNavNotifications · LteNavTasks (drop into the topbar [topbar-end] slot)
Forms — LteButton · LteInput · LteSelect · LteTextarea · LteInputSwitch · LteInputFlatpickr · LteInputTomSelect (all ControlValueAccessor + model() two-way binding)
Optional plugin wrappers lazy-load their library only when used: LteApexChart (apexcharts), LteInputFlatpickr (flatpickr), LteInputTomSelect (tom-select), LteDatatable (simple-datatables). Install the ones you need:
npm install apexcharts flatpickr tom-select simple-datatablesSelectors use the
lte-prefix (<lte-card>); class names use theLte…Componentconvention.
State is exposed through providedIn: 'root' signal services:
| Service | Responsibility |
|---|---|
ColorModeService |
light/dark/auto, data-bs-theme, localStorage persistence, system fallback |
SidebarService |
responsive collapse/overlay/mini state + <body> classes |
CommandPaletteService |
⌘K open/close + global key listener |
FullscreenService |
Fullscreen API wrapper, fullscreenchange-driven |
TreeviewService |
sidebar accordion/expand registry (provided per sidebar) |
npm install # install workspace deps
npm run build # build the library (ng-packagr) + copy AdminLTE CSS
npm start # serve the demo at http://localhost:4200
npm run build:demo # production build of the demo appThe repo is an Angular workspace: the library lives in projects/adminlte-angular, the demo that dogfoods it in projects/demo.
Modern evergreen browsers (Chrome, Edge, Firefox, Safari). Matches Bootstrap 5.3 and Angular 22 support targets.