Safeguard
Security

ng-bootstrap: Using and Securing Angular's Bootstrap Widgets

ng-bootstrap gives Angular apps native Bootstrap widgets with no jQuery dependency. Here is how to keep it current and where the real security work actually lives.

Yukti Singhal
Platform Engineer
5 min read

ng-bootstrap is a set of native Angular widgets built on Bootstrap's CSS, and its biggest security advantage is what it does not include: no jQuery, no bootstrap.js, and therefore a smaller, more auditable dependency surface. It is maintained by the Angular UI team and ships components — modals, datepickers, dropdowns, tooltips — as pure Angular directives that hook into Angular's own change detection and sanitization. That design decision matters more for security than any single config flag, because it removes an entire class of DOM-manipulation library from your bundle.

This post covers how to keep ng-bootstrap on a supported version, how it fits Angular's compatibility matrix, and where the genuine risk sits when you use it.

What ng-bootstrap is (and is not)

You install it from npm as @ng-bootstrap/ng-bootstrap. It depends on Bootstrap's stylesheet for look and feel, but reimplements all interactive behavior in Angular. That is different from loading Bootstrap's own JavaScript, which manipulates the DOM directly and historically leaned on jQuery. Because ng-bootstrap works through Angular templates and bindings, content generally flows through Angular's built-in sanitizer, which HTML-escapes interpolated values by default.

It is not a full design system and it is not ngx-bootstrap, a separate project with overlapping goals. Pick one and standardize; running both pulls in duplicate widget logic and doubles your upgrade burden.

Version and Angular compatibility

ng-bootstrap tracks Angular closely, and its major version numbers have moved to line up with the framework. The current major (v21) raised the minimum required Angular to 19.0.0 and added component entry points so applications can get slightly smaller bundles and faster builds through more granular imports.

The practical takeaway is that ng-bootstrap's supported version is tied to your Angular version. If you are on an older Angular, you need the matching older ng-bootstrap major, and if you upgrade Angular you should upgrade ng-bootstrap in the same effort. Check the peer dependency before bumping:

npm info @ng-bootstrap/ng-bootstrap peerDependencies
npm ls @angular/core @ng-bootstrap/ng-bootstrap

Mismatches here are a frequent source of confusing build errors, and they also mean you can end up stranded on an unmaintained release that no longer gets fixes.

Where the security risk actually lives

The framework escapes interpolated content, so the common failure mode is a developer deliberately bypassing that protection. The usual culprits:

  • Binding untrusted data to [innerHTML], which invokes Angular's sanitizer but is still where XSS creeps in when someone reaches for bypassSecurityTrustHtml.
  • Passing user-controlled strings into a tooltip or popover configured to render HTML.
  • Building a template dynamically from user input.

Rule of thumb: never call DomSanitizer.bypassSecurityTrust* on anything a user can influence. If you need to render user HTML, sanitize it server-side with an allowlist first, then treat the result as still-suspect.

// Risky: user content into innerHTML
@Component({
  template: `<div [innerHTML]="userContent"></div>`,
})
export class NoteComponent {
  // Only safe if userContent was sanitized upstream with an allowlist
  userContent = '';
}

Upgrade hygiene for a UI dependency

A UI library is still a dependency, and an abandoned one becomes a liability. Two habits keep ng-bootstrap healthy in a project:

First, upgrade in lockstep with Angular. Because the majors are aligned, letting Angular drift ahead means ng-bootstrap can only be updated by also jumping Angular, which turns a routine bump into a migration.

Second, monitor the whole graph, not just the top-level packages you named. Bootstrap's CSS, Angular's packages, and ng-bootstrap all pull transitive dependencies, and a known issue can hide several levels down. An SCA tool such as Safeguard can flag a vulnerable transitive package in an Angular workspace and tell you which direct dependency is pinning it, which is far faster than tracing a lockfile by hand. If you want the details, our SCA product page covers how transitive detection works.

A clean baseline

For a new Angular app that wants Bootstrap widgets:

ng add @ng-bootstrap/ng-bootstrap

ng add wires up the Bootstrap stylesheet and the module imports for you and, importantly, installs a version compatible with your current Angular. From there, standalone component imports keep your bundle lean:

import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
// import only the widgets you use

Keeping imports narrow is both a performance and a maintenance win — fewer widgets in the bundle means less code to audit.

FAQ

Does ng-bootstrap depend on jQuery?

No. That is one of its main points. ng-bootstrap reimplements Bootstrap's interactive widgets as native Angular components, so you use Bootstrap's CSS without bootstrap.js or jQuery.

How do I know which ng-bootstrap version to use?

Match it to your Angular version. The majors are aligned, and each release states a minimum Angular. Run npm info @ng-bootstrap/ng-bootstrap peerDependencies and upgrade ng-bootstrap and Angular together.

Is ng-bootstrap vulnerable to XSS?

The library relies on Angular's sanitizer, which escapes interpolated content by default. XSS almost always comes from bypassing that protection with bypassSecurityTrustHtml or rendering user HTML through [innerHTML] without sanitizing it first.

ng-bootstrap or ngx-bootstrap?

They are separate projects that solve a similar problem. Choose one and standardize. Running both increases bundle size and doubles the number of dependencies you have to keep patched.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.