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

alert90s

v1.0.15

Published

Neo Brutalism 90s style JS alert library

Readme

Alert90s

A "Neo Brutalism 90s" style JavaScript alert library. Completely standalone and dependency-free (CSS is injected automatically).

Heavily inspired by SweetAlert2. It supports many of the same API signatures (Promises, Inputs, PreConfirm, Timers, RTL), making it practically a drop-in UI replacement for existing projects that want a brutalist 90s makeover, just using the Alert90s object instead!

Installation

You can install it via npm:

npm install alert90s

Or just include the built file in your project:

<script src="path/to/alert90s.min.js"></script>

Usage

If using a bundler (Webpack, Vite, Rollup):

import Alert90s from "alert90s";

// Basic Message
Alert90s.show("Any fool can use a computer");

If using via <script> tag, the library automatically registered on the global window object as Alert90s and Swal.

Examples

1. Promises & Deny Buttons

Alert90s.fire({
  title: "Do you want to save the changes?",
  showDenyButton: true,
  showCancelButton: true,
  confirmButtonText: "Save",
  denyButtonText: `Don't save`,
}).then((result) => {
  if (result.isConfirmed) {
    Alert90s.fire("Saved!", "", "success");
  } else if (result.isDenied) {
    Alert90s.fire("Changes are not saved", "", "info");
  }
});

2. AJAX Requests & Inputs

Alert90s.fire({
  title: "Submit your Github username",
  input: "text",
  inputAttributes: {
    autocapitalize: "off",
  },
  showCancelButton: true,
  confirmButtonText: "Look up",
  showLoaderOnConfirm: true,
  preConfirm: async (login) => {
    try {
      const response = await fetch(`https://api.github.com/users/${login}`);
      if (!response.ok) {
        return Alert90s.showValidationMessage(
          `${JSON.stringify(await response.json())}`,
        );
      }
      return response.json();
    } catch (error) {
      Alert90s.showValidationMessage(`Request failed: ${error}`);
    }
  },
  allowOutsideClick: () => !Alert90s.isLoading(),
}).then((result) => {
  if (result.isConfirmed) {
    Alert90s.fire({ title: `Avatar`, imageUrl: result.value.avatar_url });
  }
});

3. RTL Support

Alert90s.fire({
  title: "هل تريد الاستمرار؟",
  icon: "question",
  iconHtml: "؟",
  confirmButtonText: "نعم",
  cancelButtonText: "لا",
  showCancelButton: true,
  showCloseButton: true,
  dir: "rtl",
});

4. Custom Animate.css Animations

Alert90s.fire({
  title: "Custom animation with Animate.css",
  showClass: { popup: "animate__animated animate__fadeInUp" },
  hideClass: { popup: "animate__animated animate__fadeOutDown" },
});

5. Toast Notification

Alert90s.fire({
  toast: true,
  position: "top-end",
  icon: "success",
  title: "Saved successfully",
  showConfirmButton: false,
  timer: 3000,
});

6. Loading Animations

// Segmented Progress Bar (NEW)
Alert90s.fire({
  title: "LOADING ASSETS...",
  loaderType: "segmented",
  didOpen: () => Alert90s.showLoading(),
});
setTimeout(() => Alert90s.hideLoading(), 7000);

// Other loaderTypes: 'hourglass', 'ascii', 'blinking', 'progress'
Alert90s.fire({
  title: "DOWNLOADING...",
  loaderType: "hourglass",
  didOpen: () => Alert90s.showLoading(),
});

7. Theme Switcher

Alert90s includes a built-in Neo-Brutalist theme toggle you can render anywhere:

Alert90s.renderThemeToggle("#my-container", {
  width: "120px",
  onChange: (isDark) => {
    console.log("Dark mode:", isDark);
  },
});

8. Input Types (Checkbox, Toggle, Select, Radio)

Alert90s supports rich form inputs inside modals. The checkbox, radio, select dropdown, and toggle switch all use SVG Brutalist designs with animated effects (checkmark draw-on, dot pop, animated arrow, slide-in menu, sliding knob).

// SVG Brutalist Checkbox
Alert90s.fire({
  title: "TERMS OF SERVICE",
  input: "checkbox",
  inputPlaceholder: "I ACCEPT THE TERMS",
}).then((result) => {
  if (result.isConfirmed) {
    Alert90s.fire("Accepted: " + result.value, "", "success");
  }
});

// SVG Brutalist Radio
Alert90s.fire({
  title: "DIFFICULTY",
  input: "radio",
  inputOptions: {
    easy: "I'm too young to die.",
    medium: "Hurt me plenty.",
    hard: "Ultra-Violence.",
  },
  inputValue: "hard",
});

// Toggle Switch
Alert90s.fire({
  title: "DARK MODE",
  input: "toggle",
  inputPlaceholder: "Enable dark mode",
});

// Select Dropdown
Alert90s.fire({
  title: "CHOOSE WEAPON",
  input: "select",
  inputOptions: {
    bfg: "BFG 9000",
    plasma: "Plasma Rifle",
    shotgun: "Super Shotgun",
  },
});

CSS-only Buttons

Alert90s also ships with a standalone CSS button library. Just add the classes to your own <button> or <a> elements for an instant neo-brutalist feel!

<!-- Base Button -->
<button class="btn90s">Base Button</button>

<!-- Color Variants -->
<button class="btn90s primary">Primary</button>
<button class="btn90s success">Success</button>
<button class="btn90s warning">Warning</button>
<button class="btn90s danger">Danger</button>
<button class="btn90s dark">Dark</button>

<!-- Sizes -->
<button class="btn90s sm primary">Small</button>
<button class="btn90s lg danger">Large</button>

Tooltips / Popovers

Alert90s includes a lightweight, built-in tooltip library that styles any element with a data-alert90s-tooltip attribute.

<!-- Basic (Top default) -->
<button data-alert90s-tooltip="I appear on top!">Hover Me</button>

<!-- Positions (top, bottom, left, right) -->
<button data-alert90s-tooltip="Bottom side!" data-alert90s-position="bottom">
  Hover
</button>

<!-- Colors (yellow, cyan, pink, base, dark) -->
<button data-alert90s-tooltip="Cyan Tooltip" data-alert90s-color="cyan">
  Hover
</button>

Note: Tooltips initialize automatically on DOMContentLoaded. If you load dynamic content later, call Alert90s.initTooltips() to initialize them.

9. Standalone Components

All SVG Brutalist inputs can be rendered anywhere on the page — no modal needed! Each returns an API object with getValue(), setValue(), and destroy().

<div id="my-checkbox"></div>
<div id="my-toggle"></div>
<div id="my-radio"></div>
<div id="my-select"></div>
// Checkbox
const cb = Alert90s.renderCheckbox("#my-checkbox", {
  label: "ACCEPT TERMS",
  checked: false,
  onChange: (checked) => console.log("Checked:", checked),
});

// Toggle Switch
const toggle = Alert90s.renderToggle("#my-toggle", {
  label: "",
  onChange: (isOn) => console.log("Toggle:", isOn),
});

// Radio Group
const radio = Alert90s.renderRadio("#my-radio", {
  options: { easy: "EASY", medium: "MEDIUM", hard: "HARD" },
  value: "medium",
  onChange: (val) => console.log("Selected:", val),
});

// Select Dropdown
const select = Alert90s.renderSelect("#my-select", {
  placeholder: "SELECT DRIVE",
  options: { a: "FLOPPY (A:)", c: "HARD DISK (C:)", d: "CD-ROM (D:)" },
  onChange: (val) => console.log("Chosen:", val),
});

// Programmatic API
cb.getValue(); // true/false
cb.setValue(true);
radio.getValue(); // 'medium'
select.setValue("c"); // updates display
cb.destroy(); // removes component

Support

If you find this project useful, you can support its development:

If you'd like to collaborate or just say hi, visit my Portfolio Website.

Advanced Options

| Option | Type | Default | Description | | ----------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------ | | background | String | '' | Custom background color for the modal. | | color | String | '' | Custom text color for the modal body. | | titleColor | String | '' | Custom title color. | | iconColor | String | '' | Custom icon color (including SVG stroke). | | title | String | '' | The title of the alert. Supports HTML. | | text/message | String | '' | The message body of the alert. | | html | String | '' | A custom HTML description for the alert. | | icon | String | '' | Standard icons: warning, error, info, success, question | | iconHtml | String | '' | Custom HTML string for the icon. | | footer | String | '' | Custom HTML for the footer section. | | imageUrl | String | '' | URL for an image to display. | | input | String | null | Input type: 'text', 'password', 'textarea', 'select', 'radio', 'checkbox' (SVG Brutalist), 'toggle'. | | inputPlaceholder | String | '' | Placeholder text or label for checkbox/toggle. | | inputValue | String | '' | Initial value or checked state (for boolean inputs). | | inputOptions | Object | {} | Object mapping {value: 'Label'} for select/radio. | | inputAttributes | Object | {} | Custom HTML attributes for the input element. | | theme | String | 'light' | Native dark mode support ('light', 'dark', or 'auto'). | | dir | String | 'auto' | Text direction. Set rtl for Arabic/Hebrew. | | position | String | 'center' | top, top-end, bottom-start, etc. | | timer | Number | null | Auto close timer in milliseconds. | | timerProgressBar | Boolean | false | Display progress bar at the bottom. | | toast | Boolean | false | Display the alert as a non-blocking toast notification. | | loaderType | String | 'hourglass' | Type of loader: hourglass, ascii, blinking, progress, segmented. | | draggable | Boolean | false | Allow moving the modal dragging its header. | | showDenyButton | Boolean | false | Show the third middle deny button. | | preConfirm | Function | null | Async function executed before confirm executes. | | allowOutsideClick | Function | null | Async function executed before confirm executes. |

Methods

  • Alert90s.fire(options) or Alert90s.show(options)
  • Alert90s.showLoading() / Alert90s.hideLoading()
  • Alert90s.showValidationMessage(message) / Alert90s.resetValidationMessage()
  • Alert90s.getTimerLeft()
  • Alert90s.getPopup()
  • Alert90s.initTooltips() / Alert90s.destroyTooltips()
  • Alert90s.renderThemeToggle(selector, options)
  • Alert90s.renderCheckbox(selector, options){ getValue, setValue, destroy }
  • Alert90s.renderToggle(selector, options){ getValue, setValue, destroy }
  • Alert90s.renderRadio(selector, options){ getValue, setValue, destroy }
  • Alert90s.renderSelect(selector, options){ getValue, setValue, destroy }

License

MIT