🚀 Let's Get Angular 20 and Bootstrap Working Together: A Quick Guide
Angular 20, which landed in May 2025, is a game-changer. It's clear the Angular team is doubling down on making our lives easier with a major focus on speed, smarter reactivity, and a cleaner development experience. But what happens when you bring an old friend like Bootstrap into the mix? You get the best of both worlds: a rock-solid, responsive design framework running on a supercharged, modern frontend engine.
This guide is here to walk you through exactly how to blend Bootstrap with Angular 20, paying close attention to the new features that change how we build things.
Latest from angular
Bookmark This Article
Your browser doesn't support automatic bookmarking. You can:
- Press Ctrl+D (or Command+D on Mac) to bookmark this page
- Or drag this link to your bookmarks bar:
Clicking this bookmarklet when on any page of our site will bookmark the current page.
So, What's the Big Deal with Angular 20?
Before we jump into the setup, let's quickly cover the headlining features of Angular 20, because they directly influence how we'll handle UI work.
Signals are Front and Center
The Signals API is now stable, and it’s a huge leap forward. Think of it as a more direct way to tell your app exactly what needs to update, without the broad strokes of Zone.js. For us, this means smoother, faster interactions with Bootstrap components.
Life in the Zoneless Lane
Perhaps the biggest shift is the move toward zoneless applications. Ditching Zone.js might sound scary, but the benefits are massive: - Lighter Apps: Your bundle sizes will thank you. - Blazing Speed: Change detection gets a serious performance boost. - Simpler Debugging: Stack traces are cleaner and easier to follow.
When working with Bootstrap, this just means we need to be a bit more intentional about triggering UI updates, especially for interactive elements.
Smarter Templates
Angular 20 gives our templates some new superpowers, like using exponentiation operators (**
) or the in
operator right in the HTML. This is great for creating dynamic Bootstrap classes on the fly without cluttering our component logic.
Getting Bootstrap and Angular 20 to Play Nice
Alright, let's get our hands dirty. Here are a few ways to get Bootstrap set up in your Angular 20 project.
Method 1: The Classic NPM Install
This is the most direct route. Just pop open your terminal and run:
npm install bootstrap
Next, you'll need to tell Angular where to find the files. Head over to your angular.json
file and update the styles
array:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
Need Bootstrap's JavaScript for things like dropdowns or modals? Add the JS bundle to the scripts
array in the same file:
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
]
This method is clean, simple, and plays well with Angular 20’s zoneless architecture since it avoids potential conflicts from libraries like jQuery.
Method 2: The Angular-Native Way with ng-bootstrap
If you want components that feel truly integrated with Angular, ng-bootstrap
is your best bet. It reimagines Bootstrap components as pure Angular directives.
ng add @ng-bootstrap/ng-bootstrap
Heads Up! Right after Angular 20 was released, there was a small hiccup. Angular renamed a function from afterRender
to afterEveryRender
, which caused some compatibility issues with ng-bootstrap
. If you hit this snag, you have two choices:
1. Check if the official ng-bootstrap
team has released a patch for Angular 20.
2. If you're feeling adventurous, look for a community fix, like the one discussed in GitHub issue #4828.
Using ng-bootstrap
is fantastic for a zoneless world because it’s built to sync with Angular's change detection, not fight against it.
Method 3: The Other Native Option, ngx-bootstrap
ngx-bootstrap
is another excellent choice that provides native Angular components for Bootstrap.
npm install ngx-bootstrap bootstrap
You can then import only the modules you need. In a traditional module-based setup, it looks like this:
import { TooltipModule } from 'ngx-bootstrap/tooltip';
@NgModule({
imports: [TooltipModule.forRoot(), ...],
})
export class AppModule { }
Or, if you're embracing the future with standalone components:
import { TooltipModule } from 'ngx-bootstrap/tooltip';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
standalone: true,
imports: [TooltipModule]
})
export class MyComponent { }
Bootstrap in the World of Standalone Components
Angular 20 continues to champion standalone components as the way forward, letting us build apps with less boilerplate.
Using Bootstrap Styles
Even in a standalone world, you'll still add the main Bootstrap CSS file to angular.json
. The magic happens inside your component, where you can import specific component libraries directly.
import { NgbAlertModule, NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: true,
imports: [NgbAlertModule, NgbAccordionModule] // Pull in just what you need
})
export class AppComponent { }
Kicking Off a Standalone App
When you bootstrap a standalone application, the setup in main.ts
is lean and clean:
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
// Add any providers your Bootstrap components might need
]
}).catch(err => console.error(err));
This fits perfectly with Angular 20's philosophy of building modular, focused applications.
Navigating the New Zoneless World
Working without Zone.js means we have more control, but also a bit more responsibility, especially with UI events.
Manually Triggering Changes
Sometimes, a Bootstrap component event (like a modal closing) might happen outside of Angular's awareness. In a zoneless app, you may need to give Angular a nudge.
import { ChangeDetectorRef } from '@angular/core';
export class MyComponent {
constructor(private cdr: ChangeDetectorRef) {}
onBootstrapEvent() {
// Do your thing...
this.cdr.detectChanges(); // "Hey Angular, look over here!"
}
}
Letting Signals Do the Heavy Lifting
A more elegant solution is to use Angular 20's Signals to manage the state of your Bootstrap components.
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-modal-example',
template: `
<button (click)="toggleModal()">Toggle Modal</button>
`
})
export class ModalExampleComponent {
isModalOpen = signal(false);
toggleModal() {
this.isModalOpen.update(value => !value);
}
}
This approach taps directly into Angular 20's new reactive core, making your UI updates incredibly efficient.
Supercharging Your App with Server-Side Rendering (SSR)
Angular 20's SSR has gotten some fantastic upgrades that change how we handle Bootstrap in server-rendered apps.
Taking Advantage of Incremental Hydration
Incremental hydration lets your server-rendered page "wake up" piece by piece as the user interacts with it. This is a huge performance win for pages with lots of Bootstrap components. The setup in your server.ts
for a standalone app would look something like this:
const _app = () => bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(ServerModule),
// ... any other providers
],
});
server.engine('html', ngExpressEngine({
bootstrap: _app
}));
This ensures your Bootstrap styles are rendered correctly on the server while giving users a fast, interactive experience on the client.
Making Bootstrap Your Own
Let's be honest, you don't want your app to look like every other Bootstrap site on the web. Customizing with Sass is the way to go.
Cooking Up a Custom Theme
Create a _variables.scss
file to put your own spin on Bootstrap's defaults.
// src/_variables.scss
$primary: #3f51b5; // A nice Material Design indigo
$font-family-base: 'Roboto', sans-serif;
$enable-responsive-font-sizes: true;
Then, import your overrides before the main Bootstrap Sass file in styles.scss
:
// styles.scss
@import './variables';
@import 'bootstrap/scss/bootstrap';
Now you have a unique design system that still benefits from Bootstrap's responsive grid and Angular 20's raw power.
Our Pro-Tips for a Smooth Ride
Based on what's new in Angular 20, here's our advice for a happy partnership with Bootstrap:
- Go Native: In a zoneless world, stick with Angular-native libraries like
ng-bootstrap
orngx-bootstrap
. They're built to work with Angular's change detection, not against it. - Embrace Signals: Use Signals to manage the state of your UI components. It’s the modern, performant way to handle reactivity in Angular.
- Optimize for SSR: Leverage Angular 20's SSR improvements. Make sure your Bootstrap integration is compatible with features like incremental hydration.
- Stay Lean: Angular 20 is all about performance. If you don't need Bootstrap's JavaScript features, consider using the CSS-only version to keep your app light.
Wrapping It Up
Pairing Bootstrap with Angular 20 is a fantastic choice. You get a powerful, familiar design framework and a cutting-edge frontend engine. By embracing the big changes in Angular 20—Signals, zoneless architecture, and smarter templates—you can build apps that are not only beautiful and responsive but also faster and easier to maintain.
Whether you're installing directly or using a native library, the trick is to align your approach with Angular 20's new architecture. Follow the tips in this guide, and you'll be well on your way to building amazing web apps that get the best of both worlds.