@ng-bootstrap/ng-bootstrap and ngx-bootstrap are both popular UI component libraries that bring Bootstrap components to Angular without requiring jQuery or Bootstrap's native JavaScript. They allow developers to use familiar Bootstrap styles while leveraging Angular's change detection, dependency injection, and component lifecycle. While they share the same visual foundation, they differ in API design, maintenance cadence, and integration depth with modern Angular features.
Both @ng-bootstrap/ng-bootstrap and ngx-bootstrap solve the same problem: they give you Bootstrap components that work natively in Angular without needing jQuery. This means you get the look and feel of Bootstrap with the performance and tooling of Angular. However, they take different approaches to implementation, configuration, and maintenance. Let's look at how they handle real engineering tasks.
@ng-bootstrap/ng-bootstrap requires the Bootstrap CSS framework but explicitly does not need Bootstrap's JavaScript files. It relies on Angular to handle interactions.
# Install the package
npm install @ng-bootstrap/ng-bootstrap
# Import the module or standalone components
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
ngx-bootstrap also requires Bootstrap CSS but no jQuery. It often provides its own CSS for specific components that need extra styling beyond standard Bootstrap.
# Install the package
npm install ngx-bootstrap
# Import specific modules to keep bundle size down
import { ModalModule } from 'ngx-bootstrap/modal';
Modals are a critical part of most dashboards. Both libraries use services to manage modals, but the API surface differs slightly.
@ng-bootstrap/ng-bootstrap uses the NgbModal service. You pass a component or template reference to the open method.
// ng-bootstrap modal usage
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({ ... })
export class MyComponent {
constructor(private modalService: NgbModal) {}
openContentModal() {
const modalRef = this.modalService.open(MyModalComponent);
modalRef.componentInstance.name = 'Angular';
}
}
ngx-bootstrap uses the BsModalService. The method is called show instead of open, and configuration is passed as a second argument.
// ngx-bootstrap modal usage
import { BsModalService } from 'ngx-bootstrap/modal';
@Component({ ... })
export class MyComponent {
constructor(private modalService: BsModalService) {}
openContentModal() {
const modalRef = this.modalService.show(MyModalComponent, {
initialState: { name: 'Angular' }
});
}
}
For simpler UI elements like tooltips, both libraries use attribute directives. The naming convention is the main difference here.
@ng-bootstrap/ng-bootstrap prefixes directives with ngb.
<!-- ng-bootstrap tooltip -->
<button
[ngbTooltip]="'Tooltip content'"
placement="top"
class="btn btn-primary">
Hover me
</button>
ngx-bootstrap prefixes directives with bs.
<!-- ngx-bootstrap tooltip -->
<button
[bsTooltip]="'Tooltip content'"
placement="top"
class="btn btn-primary">
Hover me
</button>
Datepickers are often the hardest component to get right. Both libraries offer robust solutions, but configuration styles vary.
@ng-bootstrap/ng-bootstrap provides NgbDatepicker which can be used inline or in a popup. It uses Angular forms integration out of the box.
<!-- ng-bootstrap datepicker -->
<input
class="form-control"
placeholder="yyyy-mm-dd"
name="dp"
ngbDatepicker
#d="ngbDatepicker"
(click)="d.toggle()"
[(ngModel)]="model"/>
ngx-bootstrap offers BsDatepickerModule with a focus on theming and range selection.
<!-- ngx-bootstrap datepicker -->
<input
class="form-control"
[bsConfig]="{ containerClass: 'theme-green' }"
bsDatepicker
[(bsValue)]="value"/>
This is often the deciding factor for architectural choices.
@ng-bootstrap/ng-bootstrap typically releases new major versions to match Angular major versions. If you are on Angular 17, there is a specific version of ng-bootstrap designed for it. This tight coupling reduces breaking changes during upgrades.
ngx-bootstrap has historically supported multiple Angular versions within a single library version, but release cadence has varied. For new projects, check the latest release date to ensure it keeps pace with Angular's rapid evolution.
@ng-bootstrap/ng-bootstrap relies heavily on standard Bootstrap CSS classes. To change the look, you usually override Bootstrap variables via SCSS before compiling.
// Override Bootstrap variables
$primary: #563d7c;
@import "bootstrap/scss/bootstrap";
ngx-bootstrap sometimes adds its own classes for components that Bootstrap does not cover fully (like the datepicker popup). You may need to target these specific classes in your styles.
/* Target ngx-bootstrap specific classes */
.bs-datepicker {
background-color: #f0f0f0;
}
Despite the differences, both libraries share core philosophies.
// Both allow standard Angular imports without jQuery
import 'bootstrap/dist/css/bootstrap.min.css';
# Required for both
npm install bootstrap
<!-- Both support standard tab indexing -->
<button tabindex="0" ... >Action</button>
// Both provide strong typing for services
constructor(private modal: NgbModal) {} // Typed
constructor(private modal: BsModalService) {} // Typed
// Both react to form control status
this.form.get('date').statusChanges.subscribe(...);
| Feature | Shared by Both |
|---|---|
| Dependencies | π« No jQuery required |
| Styling | π¨ Uses Bootstrap CSS |
| Language | π Written in TypeScript |
| Forms | β Supports Reactive Forms |
| Accessibility | βΏ Keyboard navigation support |
| Bundle | π¦ Tree-shakable modules |
| Feature | @ng-bootstrap/ng-bootstrap | ngx-bootstrap |
|---|---|---|
| Directive Prefix | πΉ ngb (e.g., ngbTooltip) | πΈ bs (e.g., bsTooltip) |
| Modal Method | πΉ modal.open() | πΈ modal.show() |
| Release Cycle | πΉ Tied to Angular versions | πΈ Independent versioning |
| CSS Extras | πΉ Minimal extra CSS | πΈ Some custom CSS for widgets |
| Community | πΉ Angular community maintained | πΈ Separate maintainer team |
@ng-bootstrap/ng-bootstrap is like the standard issue equipment πͺ β reliable, consistently updated, and aligned with the core Angular roadmap. It is the default choice for teams that want to minimize risk during Angular upgrades.
ngx-bootstrap is like a specialized toolkit π§° β it has historically offered more features out of the box for certain widgets. It fits well in projects that need those specific features and are already configured for it.
Final Thought: For most new Angular applications, @ng-bootstrap/ng-bootstrap offers a smoother path forward due to its alignment with Angular's release schedule. However, if your team relies on specific ngx-bootstrap components, it remains a viable option provided you monitor its maintenance status.
Choose @ng-bootstrap/ng-bootstrap if you want a library that closely tracks Angular's release cycle and is maintained by the Angular community. It is the safer bet for long-term projects requiring stability and up-to-date support for new Angular versions. Its API feels more native to Angular, using dependency injection heavily for complex components like modals.
Choose ngx-bootstrap if you rely on specific components that are more feature-rich in this library, such as advanced datepickers or complex form inputs. It is suitable for existing projects already invested in its ecosystem. However, verify current maintenance activity before starting new enterprise projects, as release velocity has historically varied compared to ng-bootstrap.
Angular widgets built from the ground up using only Bootstrap 5 CSS with APIs designed for the Angular ecosystem.
Please check our demo site and the list of issues to see all the things we are working on. Feel free to make comments there.
Please check all components we have in action at https://ng-bootstrap.github.io
The only dependencies are Angular, Bootstrap 5 CSS, and Popper.
Angular and Popper are explicitly listed as peer dependencies, while Bootstrap is not, as they don't release their CSS separately. The table below simply lists the exact version of Bootstrap CSS against which the corresponding versions of ng-bootstrap are tested.
| ng-bootstrap | Angular | Bootstrap CSS | Popper |
|---|---|---|---|
| 1.x.x | ^5.0.2 | 4.0.0 | |
| 2.x.x | ^6.0.0 | 4.0.0 | |
| 3.x.x | ^6.1.0 | 4.0.0 | |
| 4.x.x | ^7.0.0 | 4.0.0 | |
| 5.x.x | ^8.0.0 | 4.3.1 | |
| 6.x.x | ^9.0.0 | 4.4.1 | |
| 7.x.x, 8.x.x | ^10.0.0 | 4.5.0 | |
| 9.x.x | ^11.0.0 | 4.5.0 | |
| 10.x.x | ^12.0.0 | 4.5.0 | |
| 11.x.x | ^13.0.0 | 4.6.0 | |
| 12.x.x | ^13.0.0 | 5.0.0 | ^2.10.2 |
| 13.x.x | ^14.1.0 | 5.2.0 | ^2.10.2 |
| 14.x.x | ^15.0.0 | 5.2.3 | ^2.11.6 |
| 15.x.x | ^16.0.0 | 5.2.3 | ^2.11.6 |
| 16.x.x | ^17.0.0 | 5.3.2 | ^2.11.8 |
| 17.x.x | ^18.0.0 | 5.3.2 | ^2.11.8 |
| 18.x.x | ^19.0.0 | 5.3.3 | ^2.11.8 |
| 19.x.x | ^20.0.0 | 5.3.6 | ^2.11.8 |
| 20.x.x | ^21.0.0 | 5.3.8 | ^2.11.8 |
We strongly recommend using Angular CLI for setting up a new project. If you have an Angular CLI project, you could simply use our schematics to add ng-bootstrap library to it.
Just run the following:
ng add @ng-bootstrap/ng-bootstrap
It will install ng-bootstrap for the default application specified in your angular.json.
If you have multiple projects and you want to target a specific application, you could specify the --project option:
ng add @ng-bootstrap/ng-bootstrap --project myProject
If you prefer not to use schematics and install everything manually, please refer to the manual installation instructions on our website.
We support the same browsers and versions supported by both Bootstrap 4 and Angular, whichever is more restrictive. See Angular browser support and Bootstrap browser support for more details.
Our code is automatically tested on all supported browsers.
Please, do not open issues for the general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on StackOverflow where maintainers are looking at questions tagged with ng-bootstrap.
StackOverflow is a much better place to ask questions since:
To save your and our time we will be systematically closing all the issues that are requests for general support and redirecting people to StackOverflow.
We want to fix it ASAP! But before fixing a bug we need to reproduce and confirm it.
We ask you to respect two things:
A minimal reproduction scenario allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
Please note that we will be insisting on a minimal reproduction scenario in order to save maintainers time and ultimately be able to fix more bugs. We'll mark the issue as non-actionable without it and close if not heard from the reporter.
Interestingly, from our experience users often find coding problems themselves while preparing a minimal StackBlitz. We understand that sometimes it might be hard to extract essential bits of code from a larger code-base but we really need to isolate the problem before we can fix it.
Please check DEVELOPER.md for documentation on running the project locally and CONTRIBUTING.md for contribution guidelines.
Please take a moment and read our Code of Conduct