If you’ve ever had to spin up a new admin panel or internal tool, you know the drill. You hunt for a template, install it, and suddenly your node_modules folder is 800MB. You’re forced to untangle a web of complex BehaviorSubject chains, legacy RxJS logic, and a heavy component library that fights your custom CSS at every turn.
I wanted something different. I wanted a dashboard that felt lightweight, utilized modern Angular architecture (Standalone Components and Signals), and looked sharp out of the box without fighting a UI library.
Here is a technical breakdown of how I built Exo-Dash, a production-ready dashboard starter kit engineered for performance and clean architecture.
1. Dropping RxJS for UI State with Signals
RxJS is incredibly powerful for complex asynchronous data streams, but using it just to toggle a sidebar or track a dark-mode state is overkill. Angular Signals fundamentally changed how I architected the UI state for this dashboard.
By moving to Signals, the codebase became synchronous, glitch-free, and incredibly easy to read.
import { Component, signal, computed } from '@angular/core';
@Component({
selector: 'app-sidebar',
standalone: true,
template: `
<aside [class.w-64]="isOpen()" [class.w-20]="!isOpen()">
<button (click)="toggle()">Toggle</button>
<!-- Navigation links -->
</aside>
`
})
export class SidebarComponent {
// Simple, synchronous state
isOpen = signal<boolean>(true);
// Computed values update automatically
sidebarWidth = computed(() => this.isOpen() ? '256px' : '80px');
toggle() {
this.isOpen.update(v => !v);
}
}
No .subscribe(), no async pipes in the template, and no memory leak worries. The entire layout wrapper for the dashboard relies on Signals to handle mobile drawer states, theme toggles, and user session data.
2. Standalone Components & "Zoneless" Readiness
One of the biggest issues with legacy dashboard templates is the AppModule becoming a dumping ground for hundreds of declarations and third-party imports.
Exo-Dash is built entirely with Standalone Components. This means there are zero NgModule files in the project. Every single component, from the data tables to the metric cards, manages its own dependencies directly via its imports array.
Because the architecture relies on Standalone Components and fine-grained Signal reactivity, the template is heavily optimized for Angular's push toward a Zoneless future. You get a dramatically smaller initial bundle size and instant, predictable UI rendering.
3. Utility-First Styling with Tailwind CSS
Traditional Angular dashboard templates often rely on heavy UI kits (like Angular Material or Bootstrap). The problem? The moment your client asks for a specific design token or a unique table layout, you are fighting CSS encapsulation and ::ng-deep.
I ripped out the component library entirely and built the UI using pure Tailwind CSS.
This allowed me to build highly specific dashboard components—like stat cards, data tables, and navigation bars—without shipping unused CSS. Implementing Dark Mode also became a trivial configuration in Tailwind, allowing the dashboard to automatically respect the user's system preferences without shipping heavy theme stylesheets.
The Result: Exo-Dash
The end result of this architecture is Exo-Dash. It’s a clean, modern foundation for building SaaS platforms or internal tools. Because it strictly uses Standalone Components and Signals, the bundle size is tiny, and the developer experience is frictionless.
If you are tired of untangling bloated templates and want a clean slate to build your next Angular project, you can test-drive the results of this architecture.
👉 Check out the live demo here
👉 Get the source code here
I'd love to hear how you are managing state in your Angular applications. Are you fully on board the Signals train, or still holding onto RxJS for the UI? Let me know in the comments!
Top comments (0)