npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ng-toast-alerts

v1.0.3

Published

A lightweight Angular toast notification and alert library with simple integration and customizable messages.

Readme

ng-toast-alerts

A lightweight, zero-dependency Angular toast notification library with support for NgModule and Standalone apps.

npm version npm downloads license


Table of Contents


Features

  • ✅ 4 toast types — success, error, warning, info
  • ⏱ Auto-dismiss — configurable per toast, or disable it entirely
  • 📚 Stackable — multiple toasts appear simultaneously
  • 🎨 Progress bar — animated countdown shows how long the toast has left
  • ♿ Accessible — uses aria-live, role="alert", and proper focus management
  • 📦 Works everywhere — NgModule apps, Standalone apps, lazy-loaded modules
  • 🚫 Zero dependencies — no extra packages, just Angular + RxJS (already in your project)
  • 🪶 Tiny — ~15KB unpacked

Requirements

| Package | Minimum version | |---|---| | @angular/core | 15.0.0 | | @angular/common | 15.0.0 | | rxjs | 7.0.0 |

Angular 15, 16, and 17 are all supported.


Installation

npm install ng-toast-alerts

Setup

Option A — NgModule-based app (classic)

This is the setup for apps that use AppModule.

Step 1 — Import the module in app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgToastAlertsModule } from 'ng-toast-alerts';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    NgToastAlertsModule.forRoot()  // always call forRoot() in AppModule only
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Important: Only call forRoot() in AppModule. Do not call it in feature or lazy-loaded modules — this would create a second instance of ToastService.

Step 2 — Add the container to app.component.html

<!-- Place this once at the root level of your app -->
<ng-toast-container></ng-toast-container>

<router-outlet></router-outlet>

Option B — Standalone app (Angular 15+)

This is the setup for apps bootstrapped with bootstrapApplication.

Step 1 — Register the service in main.ts

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { ToastService } from 'ng-toast-alerts';

bootstrapApplication(AppComponent, {
  providers: [
    ToastService  // registers the singleton
  ]
});

Step 2 — Import the container component in app.component.ts

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ToastContainerComponent } from 'ng-toast-alerts';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    RouterOutlet,
    ToastContainerComponent  // add this
  ],
  template: `
    <ng-toast-container></ng-toast-container>
    <router-outlet></router-outlet>
  `
})
export class AppComponent {}

Basic Usage

Inject ToastService into any component, service, guard, or interceptor and call the notification methods.

import { Component } from '@angular/core';
import { ToastService } from 'ng-toast-alerts';

@Component({
  selector: 'app-example',
  template: `
    <button (click)="onSave()">Save</button>
    <button (click)="onDelete()">Delete</button>
  `
})
export class ExampleComponent {

  constructor(private toast: ToastService) {}

  onSave(): void {
    this.toast.success('Your changes have been saved.');
  }

  onDelete(): void {
    this.toast.error('Failed to delete item.', { title: 'Error' });
  }
}

Toast Types

There are four built-in toast types, each with its own color and icon.

| Type | Method | Color | Icon | Default Duration | |---|---|---|---|---| | Success | toast.success() | Green #22c55e | ✔ | 3000ms | | Error | toast.error() | Red #ef4444 | ✖ | 5000ms | | Warning | toast.warning() | Amber #f59e0b | ⚠ | 3000ms | | Info | toast.info() | Blue #3b82f6 | ℹ | 3000ms |

Error toasts default to 5 seconds (instead of 3) because errors usually need more reading time.


API Reference

ToastService

The main service you inject and use throughout your application.

success(message, options?)

Shows a green success notification.

this.toast.success('Profile updated successfully.');

// with options
this.toast.success('File uploaded.', {
  title: 'Upload Complete',
  duration: 4000
});

error(message, options?)

Shows a red error notification. Defaults to 5000ms duration.

this.toast.error('Could not connect to the server.');

// with options
this.toast.error('Invalid email or password.', {
  title: 'Login Failed',
  duration: 7000
});

warning(message, options?)

Shows an amber warning notification.

this.toast.warning('Your session will expire in 5 minutes.');

// with options
this.toast.warning('Unsaved changes will be lost.', {
  title: 'Warning',
  duration: 0  // stays until user dismisses it
});

info(message, options?)

Shows a blue informational notification.

this.toast.info('A new version of the app is available.');

// with options
this.toast.info('Scheduled maintenance at midnight.', {
  title: 'Notice',
  duration: 6000
});

dismiss(id)

Manually dismisses a specific toast by its ID. The ID is returned from each toast method call. Useful when you want programmatic control over when a toast disappears.

// save the returned id
const id = this.toast.info('Processing your request...', { duration: 0 });

// later, when done — dismiss it
this.apiService.process().subscribe(() => {
  this.toast.dismiss(id);
  this.toast.success('Done!');
});

Note: In the current version, toast methods return void. To use dismiss(id) programmatically, subscribe to toasts$ to find the ID, or use clear() instead.


clear()

Dismisses all active toasts immediately.

this.toast.clear();

Useful when navigating away from a page and you want to clean up all pending notifications.


toasts$

An Observable<Toast[]> that emits the current list of active toasts. The ToastContainerComponent subscribes to this internally, but you can also use it yourself for custom rendering.

import { ToastService, Toast } from 'ng-toast-alerts';

export class MyComponent {
  toasts$ = this.toast.toasts$;

  constructor(private toast: ToastService) {}
}

ToastOptions

An optional configuration object passed as the second argument to any toast method.

interface ToastOptions {
  title?: string;
  duration?: number;
}

| Property | Type | Default | Description | |---|---|---|---| | title | string | undefined | Optional bold heading shown above the message | | duration | number | 3000 (error: 5000) | Time in milliseconds before the toast auto-dismisses. Set to 0 to keep it open until the user closes it manually |

Examples:

// no options — uses defaults
this.toast.success('Done!');

// with title only
this.toast.error('Something went wrong.', { title: 'Error' });

// with custom duration
this.toast.warning('Low disk space.', { duration: 10000 });

// persistent — never auto-dismisses
this.toast.info('You have 3 unread messages.', { duration: 0 });

// both title and duration
this.toast.success('Report generated.', {
  title: 'Export Complete',
  duration: 5000
});

Toast Interface

Each toast object has the following shape. You usually don't work with this directly unless building a custom container.

interface Toast {
  id: string;        // unique id like "toast-1694512345678-abc12"
  message: string;   // the notification text
  type: ToastType;   // 'success' | 'error' | 'warning' | 'info'
  duration: number;  // auto-dismiss time in ms (0 = persistent)
  title?: string;    // optional heading
}

type ToastType = 'success' | 'error' | 'warning' | 'info';

ToastContainerComponent

The UI component that renders all active toasts. Place it once at the root of your app.

<ng-toast-container></ng-toast-container>

Selector: ng-toast-container

Behavior:

  • Toasts stack vertically from bottom-right
  • New toasts appear with a slide-in animation from the right
  • Each toast has a shrinking progress bar showing time remaining
  • Clicking × on a toast dismisses it immediately
  • Toasts disappear automatically after their duration

You do not need to pass any inputs — it subscribes to ToastService automatically.


NgToastAlertsModule

For NgModule-based apps. Always use forRoot() when importing in AppModule.

NgToastAlertsModule.forRoot()

Exports: ToastContainerComponent

Provides: ToastService (singleton)


Real-World Examples

HTTP Interceptor — show error toasts on failed API calls

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse } from '@angular/common/http';
import { catchError, throwError } from 'rxjs';
import { ToastService } from 'ng-toast-alerts';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

  constructor(private toast: ToastService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    return next.handle(req).pipe(
      catchError((error: HttpErrorResponse) => {
        const message = error.error?.message || 'An unexpected error occurred.';
        this.toast.error(message, { title: `Error ${error.status}` });
        return throwError(() => error);
      })
    );
  }
}

Form submit — success and error feedback

@Component({ ... })
export class ContactFormComponent {
  form = this.fb.group({
    name: ['', Validators.required],
    email: ['', [Validators.required, Validators.email]],
    message: ['', Validators.required]
  });

  constructor(
    private fb: FormBuilder,
    private api: ContactService,
    private toast: ToastService
  ) {}

  submit(): void {
    if (this.form.invalid) {
      this.toast.warning('Please fill in all required fields.', { title: 'Validation' });
      return;
    }

    this.api.send(this.form.value).subscribe({
      next: () => {
        this.toast.success('Your message has been sent!', { title: 'Thank you' });
        this.form.reset();
      },
      error: () => {
        this.toast.error('Could not send your message. Please try again.', { title: 'Failed' });
      }
    });
  }
}

Auth guard — inform user why they were redirected

import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';
import { ToastService } from 'ng-toast-alerts';

export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService);
  const router = inject(Router);
  const toast = inject(ToastService);

  if (auth.isLoggedIn()) {
    return true;
  }

  toast.warning('Please log in to access this page.', { title: 'Access Denied' });
  router.navigate(['/login']);
  return false;
};

Route change — clear toasts on navigation

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { filter } from 'rxjs';
import { ToastService } from 'ng-toast-alerts';

@Component({
  selector: 'app-root',
  template: `
    <ng-toast-container></ng-toast-container>
    <router-outlet></router-outlet>
  `
})
export class AppComponent implements OnInit {

  constructor(
    private router: Router,
    private toast: ToastService
  ) {}

  ngOnInit(): void {
    this.router.events
      .pipe(filter(e => e instanceof NavigationStart))
      .subscribe(() => this.toast.clear());
  }
}

Accessibility

ng-toast-alerts is built with accessibility in mind:

  • The container uses aria-live="polite" so screen readers announce new toasts without interrupting the user
  • Each toast has role="alert" for immediate screen reader announcement when needed
  • Each toast includes an aria-label describing its type and message
  • The dismiss button has aria-label="Dismiss notification" for screen readers
  • Color is never the sole means of conveying type — icons are always present alongside color

Styling & Customization

All styles are scoped inside the component and applied via CSS classes. You can override them in your global styles.css:

/* Change position — top-right instead of bottom-right */
ng-toast-container .ng-toast-container {
  bottom: auto;
  top: 1.5rem;
}

/* Make toasts wider */
ng-toast-container .ng-toast-container {
  max-width: 480px;
}

/* Custom success color */
ng-toast-container .ng-toast--success {
  border-color: #0d9488;
}

/* Larger font */
ng-toast-container .ng-toast {
  font-size: 1rem;
}

CSS class reference

| Class | Element | |---|---| | .ng-toast-container | The outer wrapper (fixed position) | | .ng-toast | Individual toast card | | .ng-toast--success | Applied when type is success | | .ng-toast--error | Applied when type is error | | .ng-toast--warning | Applied when type is warning | | .ng-toast--info | Applied when type is info | | .ng-toast__icon | The emoji icon | | .ng-toast__body | Wrapper for title + message | | .ng-toast__title | The bold title text | | .ng-toast__message | The main message text | | .ng-toast__close | The × dismiss button | | .ng-toast__progress | The animated progress bar |


FAQ

Q: Can I show a toast from a service (not a component)?

Yes. Just inject ToastService into any Angular class — component, service, guard, interceptor, or resolver.


Q: What happens if I call forRoot() in a lazy-loaded module?

A second instance of ToastService is created, meaning toasts shown from that module won't appear in the container. Always call forRoot() only in AppModule.


Q: Can I show multiple toasts at the same time?

Yes. Each call to success(), error(), etc. adds a new toast to the stack. They all display simultaneously and dismiss independently.


Q: How do I make a toast stay forever until the user closes it?

Pass duration: 0:

this.toast.warning('Please review before submitting.', { duration: 0 });

Q: Can I use this with server-side rendering (SSR / Angular Universal)?

The library uses setTimeout and DOM-dependent styles which are browser-only. Wrap toast calls in a platform check to avoid SSR issues:

import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID, inject } from '@angular/core';

const platformId = inject(PLATFORM_ID);

if (isPlatformBrowser(platformId)) {
  this.toast.success('Loaded!');
}

Q: Can I change the position of the toasts?

Yes, override the .ng-toast-container CSS class in your global stylesheet. See the Styling section above.


Changelog

1.0.0 — Initial release

  • ToastService with success, error, warning, info, dismiss, clear
  • ToastContainerComponent with progress bar and slide animation
  • NgToastAlertsModule with forRoot() pattern
  • Standalone app support
  • Full accessibility support

Contributing

Contributions, issues, and feature requests are welcome.

  1. Fork the repository
  2. Create a branch: git checkout -b feat/my-feature
  3. Commit your changes: git commit -m "feat: add my feature"
  4. Push to the branch: git push origin feat/my-feature
  5. Open a Pull Request

License

MIT © saurabhkumar yadav