ngx-toastr vs angular2-notifications vs sweetalert2
Notification and Alert Libraries for Angular Applications
ngx-toastrangular2-notificationssweetalert2Similar Packages:

Notification and Alert Libraries for Angular Applications

angular2-notifications, ngx-toastr, and sweetalert2 are all popular npm packages used to display user feedback in web applications, but they serve different interaction patterns and design goals. angular2-notifications provides a flexible system for managing toast-style notifications with built-in positioning and stacking. ngx-toastr is an Angular wrapper around the lightweight toastr library, offering simple, non-blocking toast messages with minimal configuration. sweetalert2 delivers rich, modal-style alerts that pause user interaction until dismissed, supporting complex content like inputs, images, and dynamic updates. All three integrate well with Angular but differ significantly in UX philosophy, API structure, and use cases.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
ngx-toastr543,4532,578175 kB788 months agoMIT
angular2-notifications0739244 kB833 years agoMIT
sweetalert2018,0991.22 MB45 months agoMIT

Notification Patterns Compared: angular2-notifications vs ngx-toastr vs sweetalert2

When building Angular applications, choosing the right user feedback mechanism depends on whether you need non-blocking toasts or blocking modals. Let’s compare how these three libraries handle real-world scenarios.

📣 Core Interaction Model: Toasts vs Modals

angular2-notifications and ngx-toastr both implement toast notifications — small, transient messages that appear briefly without stopping user interaction. They auto-dismiss and stack in corners of the screen.

sweetalert2, by contrast, shows modal dialogs that overlay the entire UI and require user action (like clicking “OK” or “Cancel”) before continuing. This is critical for confirmations or data entry prompts.

// angular2-notifications: non-blocking toast
this.notificationsService.success('Title', 'Message');

// ngx-toastr: non-blocking toast
this.toastr.success('Message', 'Title');

// sweetalert2: blocking modal
await Swal.fire('Title', 'Message', 'success'); // pauses execution until closed

⚙️ Setup and Module Integration

All three require Angular module registration, but their initialization differs.

angular2-notifications uses a dedicated <simple-notifications> component in your app root:

<!-- app.component.html -->
<simple-notifications [options]="notificationOptions"></simple-notifications>
// app.module.ts
import { SimpleNotificationsModule } from 'angular2-notifications';
@NgModule({
  imports: [SimpleNotificationsModule.forRoot()]
})

ngx-toastr injects styles globally and doesn’t require a template element:

// app.module.ts
import { ToastrModule } from 'ngx-toastr';
@NgModule({
  imports: [
    ToastrModule.forRoot({
      timeOut: 3000,
      positionClass: 'toast-top-right'
    })
  ]
})

sweetalert2 needs no Angular module setup but requires importing CSS:

// In your component
import Swal from 'sweetalert2';

💡 Note: sweetalert2 is framework-agnostic, so it works in any JS environment, not just Angular.

🎨 Customization and Content Flexibility

angular2-notifications supports custom templates via @Input() bindings and allows per-notification overrides:

this.notificationsService.html(
  '<b>Custom HTML</b>',
  { type: 'success', timeOut: 5000 }
);

ngx-toastr offers limited HTML support and relies on predefined types (success, error, etc.). Custom components require extending base classes.

// Basic usage only
this.toastr.info('Plain text or <em>minimal HTML</em>', 'Title');

sweetalert2 excels at rich content — you can embed inputs, images, and even update content dynamically after opening:

const { value: email } = await Swal.fire({
  title: 'Enter your email',
  input: 'email',
  inputPlaceholder: 'example@domain.com'
});

// Later, update an open alert
Swal.update({
  title: 'Processing...',
  allowEscapeKey: false,
  showConfirmButton: false
});

🔄 Programmatic Control and Lifecycle

angular2-notifications returns a unique ID for each notification, allowing manual removal:

const id = this.notificationsService.success('Title', 'Message');
// Later
this.notificationsService.remove(id);

ngx-toastr returns a Toast instance with methods like close():

const toast = this.toastr.warning('Will auto-close');
toast.onHidden.subscribe(() => console.log('Gone'));

sweetalert2 provides full promise-based control and exposes methods like close(), disableButtons(), and reactive updates:

Swal.fire({
  title: 'Loading...',
  didOpen: () => {
    Swal.showLoading();
    fetchData().then(result => {
      Swal.update({
        title: 'Done!',
        text: result,
        icon: 'success'
      });
    });
  }
});

🧪 Testing and Debugging Considerations

  • angular2-notifications: Requires mocking the NotificationsService in unit tests. The DOM-based component can complicate shallow rendering.
  • ngx-toastr: Easier to test since toasts are appended to the body; you can spy on ToastrService methods.
  • sweetalert2: Use Swal.mixin({ ... }) for consistent defaults, and leverage Swal.isVisible() in E2E tests to wait for modals.

⚠️ Maintenance and Deprecation Status

As of 2024, angular2-notifications shows signs of reduced maintenance. Its last major update was years ago, and it hasn’t fully embraced modern Angular features like standalone components. While not officially deprecated, it’s risky for new greenfield projects.

ngx-toastr and sweetalert2 are both actively maintained, with regular releases and strong community support.

🆚 Summary: When to Use Which

Use CaseBest ChoiceWhy
Auto-dismissing status messagesngx-toastrLightweight, simple, zero-template setup
Custom-styled toasts with dynamic contentangular2-notificationsFlexible templating and positioning (but verify maintenance status)
User confirmations, input promptssweetalert2Modal behavior, rich interactivity, active development
Critical alerts requiring acknowledgmentsweetalert2Blocks UI until resolved
High-volume notification systemsngx-toastrEfficient DOM handling and stacking

💡 Final Recommendation

  • For most Angular apps needing simple toasts, go with ngx-toastr — it’s reliable, minimal, and integrates cleanly.
  • If you require modal dialogs with user input, sweetalert2 is the clear winner and works great alongside Angular.
  • Avoid angular2-notifications in new projects unless you have legacy compatibility needs or can commit to maintaining a fork. Its architecture feels dated compared to modern alternatives.

Remember: toasts should inform; modals should demand action. Choose the tool that matches your user experience intent.

How to Choose: ngx-toastr vs angular2-notifications vs sweetalert2

  • ngx-toastr:

    Choose ngx-toastr if you want a lightweight, battle-tested toast notification solution that’s easy to set up and integrates seamlessly with Angular’s change detection. It’s perfect for standard use cases like showing brief success or error messages that auto-dismiss and don’t interrupt user flow. Its simplicity and minimal footprint make it a solid choice for teams prioritizing stability and low cognitive overhead.

  • angular2-notifications:

    Choose angular2-notifications if you need a highly customizable notification system with fine-grained control over positioning, animation, and lifecycle management within an Angular application. It’s ideal when you want to manage multiple notification types (success, error, info, warn) with custom templates or dynamic behavior without relying on global DOM manipulation. However, note that the package has not seen active maintenance in recent years, so evaluate its long-term viability for new projects.

  • sweetalert2:

    Choose sweetalert2 when you need modal dialogs that require explicit user interaction—such as confirmations, form prompts, or critical alerts. It shines in scenarios where you must pause the application flow until the user responds, and it supports rich content including inputs, checkboxes, and dynamic updates. While not Angular-specific, it works well in Angular apps via service wrappers and is actively maintained with a robust feature set.

README for ngx-toastr

Angular Toastr

ngx-toastr


npm codecov

DEMO: https://ngx-toastr.vercel.app

Features

  • Toast Component Injection without being passed ViewContainerRef
  • No use of @for. Fewer dirty checks and higher performance
  • No use of @angular/animations
  • AoT compilation and lazy loading compatible
  • Component inheritance for custom toasts
  • SystemJS/UMD rollup bundle
  • Output toasts to an optional target directive

Dependencies

Latest version available for each version of Angular

ngx-toastrAngular
13.2.110.x 11.x
14.3.012.x 13.x
15.2.214.x.
16.2.015.x
17.0.216.x
18.x 19x>= 17.x < 23.x
current>= 20.x

Install

npm install ngx-toastr --save

Setup

step 1: add css

  • copy toast css to your project.
  • If you are using sass you can import the css.
// regular style toast
@import 'ngx-toastr/toastr';

// bootstrap style toast
// or import a bootstrap 4 alert styled design (SASS ONLY)
// should be after your bootstrap imports, it uses bs4 variables, mixins, functions
@import 'ngx-toastr/toastr-bs4-alert';

// if you'd like to use it without importing all of bootstrap it requires
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
// bootstrap 4
@import 'ngx-toastr/toastr-bs4-alert';
// boostrap 5
@import 'ngx-toastr/toastr-bs5-alert';
  • If you are using angular-cli you can add it to your angular.json
"styles": [
  "styles.scss",
  "node_modules/ngx-toastr/toastr.css" // try adding '../' if you're using angular cli before 6
]

step 2: add ToastrModule to app NgModule, or provideToastr to providers.

  • Module based
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  imports: [
    ToastrModule.forRoot(), // ToastrModule added
  ],
  bootstrap: [App],
  declarations: [App],
})
class MainModule {}
  • Standalone
import { AppComponent } from './src/app.component';
import { provideToastr } from 'ngx-toastr';

bootstrapApplication(AppComponent, {
  providers: [
    provideToastr(), // Toastr providers
  ]
});

Use

import { ToastrService } from 'ngx-toastr';
import { inject } from '@angular/core';

@Component({...})
export class YourComponent {
  toastr = inject(ToastrService);

  showSuccess() {
    this.toastr.success('Hello world!', 'Toastr fun!');
  }
}

Options

There are individual options and global options.

Individual Options

Passed to ToastrService.success/error/warning/info/show()

OptionTypeDefaultDescription
toastComponentComponentToastAngular component that will be used
closeButtonbooleanfalseShow close button
timeOutnumber5000Time to live in milliseconds
extendedTimeOutnumber1000Time to close after a user hovers over toast
disableTimeOutboolean | 'timeOut' | 'extendedTimeOut'falseDisable both timeOut and extendedTimeOut when set to true. Allows specifying which timeOut to disable, either: timeOut or extendedTimeOut
easingstring'ease-in'Toast component easing
easeTimestring | number300Time spent easing
enableHtmlbooleanfalseAllow html in message
newestOnTopbooleantrueNew toast placement
progressBarbooleanfalseShow progress bar
progressAnimation'decreasing' | 'increasing''decreasing'Changes the animation of the progress bar.
toastClassstring'ngx-toastr'CSS class(es) for toast
positionClassstring'toast-top-right'CSS class(es) for toast container
titleClassstring'toast-title'CSS class(es) for inside toast on title
messageClassstring'toast-message'CSS class(es) for inside toast on message
tapToDismissbooleantrueClose on click
onActivateTickbooleanfalseFires changeDetectorRef.detectChanges() when activated. Helps show toast from asynchronous events outside of Angular's change detection

Setting Individual Options

success, error, info, warning take (message, title, ToastConfig) pass an options object to replace any default option.

this.toastrService.error('everything is broken', 'Major Error', {
  timeOut: 3000,
});

Global Options

All individual options can be overridden in the global options to affect all toasts. In addition, global options include the following options:

OptionTypeDefaultDescription
maxOpenednumber0Max toasts opened. Toasts will be queued. 0 is unlimited
autoDismissbooleanfalseDismiss current toast when max is reached
iconClassesobjectsee belowClasses used on toastr service methods
preventDuplicatesbooleanfalseBlock duplicate messages
countDuplicatesbooleanfalseDisplays a duplicates counter (preventDuplicates must be true). Toast must have a title and duplicate message
resetTimeoutOnDuplicatebooleanfalseReset toast timeout on duplicate (preventDuplicates must be true)
includeTitleDuplicatesbooleanfalseInclude the title of a toast when checking for duplicates (by default only message is compared)
iconClasses defaults
iconClasses = {
  error: 'toast-error',
  info: 'toast-info',
  success: 'toast-success',
  warning: 'toast-warning',
};

Setting Global Options

Pass values to ToastrModule.forRoot() or provideToastr() to set global options.

  • Module based
// root app NgModule
imports: [
  ToastrModule.forRoot({
    timeOut: 10000,
    positionClass: 'toast-bottom-right',
    preventDuplicates: true,
  }),
],
  • Standalone
import { AppComponent } from './src/app.component';
import { provideToastr } from 'ngx-toastr';

bootstrapApplication(AppComponent, {
  providers: [
    provideToastr({
      timeOut: 10000,
      positionClass: 'toast-bottom-right',
      preventDuplicates: true,
    }), 
  ]
});

Toastr Service methods return:

export interface ActiveToast {
  /** Your Toast ID. Use this to close it individually */
  toastId: number;
  /** the title of your toast. Stored to prevent duplicates if includeTitleDuplicates set */
  title: string;
  /** the message of your toast. Stored to prevent duplicates */
  message: string;
  /** a reference to the component see portal.ts */
  portal: ComponentRef<any>;
  /** a reference to your toast */
  toastRef: ToastRef<any>;
  /** triggered when toast is active */
  onShown: Observable<any>;
  /** triggered when toast is destroyed */
  onHidden: Observable<any>;
  /** triggered on toast click */
  onTap: Observable<any>;
  /** available for your use in custom toast */
  onAction: Observable<any>;
}

Put toasts in your own container

Put toasts in a specific div inside your application. This should probably be somewhere that doesn't get deleted. Add ToastContainerDirective to the ngModule where you need the directive available. Make sure that your container has an aria-live="polite" attribute, so that any time a toast is injected into the container it is announced by screen readers.

import { NgModule } from '@angular/core';
import { ToastrModule, ToastContainerDirective } from 'ngx-toastr';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    ToastrModule.forRoot({ positionClass: 'inline' }),
    ToastContainerDirective,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Add a div with toastContainer directive on it.

import { Component, OnInit, viewChild, inject } from '@angular/core';
import { ToastContainerDirective, ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-root',
  template: `
    <h1><a (click)="onClick()">Click</a></h1>
    <div aria-live="polite" toastContainer></div>
  `,
})
export class AppComponent implements OnInit {
  toastContainer = viewChild(ToastContainerDirective, { static: true });
  toastrService = inject(ToastrService);

  ngOnInit() {
    this.toastrService.overlayContainer = this.toastContainer;
  }
  onClick() {
    this.toastrService.success('in div');
  }
}

Functions

Clear

Remove all or a single toast by optional id

toastrService.clear(toastId?: number);
Remove

Remove and destroy a single toast by id

toastrService.remove(toastId: number);

SystemJS

If you are using SystemJS, you should also adjust your configuration to point to the UMD bundle.

In your SystemJS config file, map needs to tell the System loader where to look for ngx-toastr:

map: {
  'ngx-toastr': 'node_modules/ngx-toastr/bundles/ngx-toastr.umd.min.js',
}

Setup Without Animations

If you do not want animations you can override the default toast component in the global config to use ToastNoAnimation instead of the default one.

In your main module (ex: app.module.ts)

import { ToastrModule, ToastNoAnimation, ToastNoAnimationModule } from 'ngx-toastr';

@NgModule({
  imports: [
    // ...
    ToastNoAnimationModule.forRoot(),
  ],
  // ...
})
class AppModule {}

That's it! No animations.

Using A Custom Toast

Create your toast component extending Toast see the demo's pink toast for an example https://github.com/scttcper/ngx-toastr/blob/master/src/app/pink.toast.ts

import { ToastrModule } from 'ngx-toastr';

@NgModule({
  imports: [
    ToastrModule.forRoot({
      toastComponent: YourToastComponent, // added custom toast!
    }),
  ],
  bootstrap: [App],
  declarations: [App, YourToastComponent], // add!
})
class AppModule {}

FAQ

  1. ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked
    When opening a toast inside an angular lifecycle wrap it in setTimeout
ngOnInit() {
    setTimeout(() => this.toastr.success('sup'))
}
  1. Change default icons (check, warning sign, etc)
    Overwrite the css background-image: https://github.com/scttcper/ngx-toastr/blob/master/src/lib/toastr.css.
  2. How do I use this in an ErrorHandler?
    See: https://github.com/scttcper/ngx-toastr/issues/179.
  3. How can I translate messages?
    See: https://github.com/scttcper/ngx-toastr/issues/201.
  4. How to handle toastr click/tap action?
    showToaster() {
      this.toastr.success('Hello world!', 'Toastr fun!')
        .onTap
        .pipe(take(1))
        .subscribe(() => this.toasterClickedHandler());
    }
    
    toasterClickedHandler() {
      console.log('Toastr clicked');
    }
    
  5. How to customize styling without overridding defaults?
    Add multiple CSS classes separated by a space:
    toastClass: 'yourclass ngx-toastr'
    
    See: https://github.com/scttcper/ngx-toastr/issues/594.

Previous Works

toastr original toastr
angular-toastr AngularJS toastr
notyf notyf (css)

License

MIT


GitHub @scttcper  ·  Twitter @scttcper