Best JavaScript Modal Libraries (2026): 6 Dialog Options Compared
Short answer. If you write your own CSS, start with the native <dialog> element: showModal() gives you a modal in the browser’s top layer, stacked dialogs, a non-modal mode and a cancelable close, with no library at all. Web Awesome Dialog (MIT) wraps the native element with a header, a close button, a footer slot, light dismiss and page scroll lock. Micromodal and a11y-dialog are tiny, unstyled scripts that handle opening and closing your own markup, and both support nested dialogs. If your project already uses Bootstrap, the Bootstrap modal remains the most complete styled option, with sizes, responsive fullscreen and scrollable bodies. The CoreUI modal is the same component in CoreUI’s styling: use it when your app is built on CoreUI, not as an upgrade over Bootstrap.
How we compared
We compared six dialog options for plain JavaScript in October 2026 against a 23-feature modal checklist: the HTML <dialog> element (per the HTML specification and MDN), Web Awesome 3.14.0 wa-dialog, micromodal 0.7.0, a11y-dialog 8.1.5, the Bootstrap 5.3.8 modal and the CoreUI for Bootstrap modal from the free @coreui/coreui 5.9.1 package.
Each cell comes from the vendor’s documentation, its source code or a test in a public demo. We mark a feature as missing (❌) only when the vendor’s docs say so or we reproduced it in a demo. When the docs are silent we show — (no data). This page covers features only. CoreUI publishes this page; its row follows the same rules.
The comparison at a glance
✅ built in and documented · Partial = a recipe in the docs, a workaround, or limited browser support · ❌ absence confirmed by the vendor or in a demo · — no data
| Option (version) | License | Ships styles | Size presets | Responsive fullscreen | Header, body, footer | Scrollable body | Backdrop click control | Page scroll lock | Nested dialogs | Non-modal mode | Cancelable close | Animation |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Native <dialog> (HTML standard) |
n/a | Browser defaults | — | — | — | Partial (your CSS) | Partial (closedby, not in Safari) |
— | ✅ | ✅ | ✅ | Partial (your CSS) |
| Web Awesome Dialog (3.14.0) | MIT | ✅ | Partial (--width) |
— | ✅ | ✅ | ✅ | ✅ | Partial | — | ✅ | ✅ |
| Micromodal (0.7.0) | MIT in repo, ISC in npm | ❌ | ❌ | ❌ | Partial (markup to copy) | ❌ | ✅ | ✅ | ✅ | — | — | Partial (your CSS) |
| a11y-dialog (8.1.5) | MIT | ❌ | ❌ | ❌ | Partial (markup to copy) | ❌ | ✅ | Partial (CSS recipe) | ✅ | — | ✅ | Partial (CSS recipe) |
| Bootstrap modal (5.3.8) | MIT | ✅ | ✅ sm, lg, xl | ✅ | ✅ | ✅ | ✅ (static backdrop) | ✅ | ❌ | Partial | ✅ | ✅ |
| CoreUI modal (coreui 5.9.1) | MIT | ✅ | ✅ sm, lg, xl | ✅ | ✅ | ✅ | ✅ (static backdrop) | ✅ | ❌ | Partial | ✅ | ✅ |
The options, one by one
The native dialog element
<dialog> has been supported in all major browsers since March 2022 (Firefox 98 and Safari 15.4). showModal() opens it in the top layer, above everything else on the page regardless of overflow or z-index on its ancestors, which removes the reason many libraries move modals around the DOM. Later modals stack above earlier ones, show() opens a non-modal dialog, the cancel event can be canceled, requestClose() and returnValue cover confirm-style flows, and a <form method="dialog"> closes it on submit. The closedby="any" attribute closes it on a backdrop click in Chrome and Edge 134+ and Firefox 141+, but not yet in Safari. Everything visual is yours: there is no header, footer, size or fullscreen preset, and animations use @starting-style in your CSS.
Choose it if you have your own design system and want zero dependencies.
Web Awesome Dialog
Web Awesome is the successor of Shoelace (the Shoelace repository is archived). Its MIT wa-dialog is built on the native <dialog>, so it inherits top-layer rendering, and adds a header with a label and a close button, header-actions and footer slots, a body that scrolls while the header and footer stay in view, light-dismiss for closing on a backdrop click (off by default), page scroll lock, and a wa-hide event you can cancel, with the source of the close request in event.detail. Width is a CSS custom property and animation timing comes from --show-duration and --hide-duration. There are no size presets or fullscreen mode, and side panels are a separate wa-drawer. It brings its own theme system rather than Bootstrap styles.
Choose it if you want native dialog behavior with a ready header and footer, outside the Bootstrap look.
Micromodal
Micromodal 0.7.0 (June 3, 2026, no dependencies) is a very small script. You copy the recommended markup, and it handles showing and closing it: data-micromodal-trigger and data-micromodal-close attributes, MicroModal.show(), close() and the new closeAll(), onShow and onClose callbacks, optional page scroll lock with disableScroll, and hooks that wait for your CSS animations. Version 0.7.0 added nested (layered) modals. Its docs state that it makes no stylistic choices and ships no styles, so sizes, fullscreen and scrolling are your CSS. The license field differs between the repository (MIT) and npm (ISC); check it if your legal review cares.
Choose it if you want the smallest script and full control of the markup.
a11y-dialog
a11y-dialog 8.1.5 (MIT, February 2026, one small dependency) is another unstyled script around your own markup. It provides show(), hide() and destroy(), a shown property and show, hide and destroy events that can all be canceled with preventDefault(). Nested dialogs are supported, with only the top one closing on a backdrop click. Its docs say the script takes care of no styling at all, and they give CSS recipes for page scroll lock and animations instead of built-in options.
Choose it if you want a small, unstyled script with cancelable events and nested dialogs.
Bootstrap modal
The Bootstrap 5.3 modal is the most complete styled dialog here. You get .modal-sm (300 px), the default 500 px, .modal-lg (800 px) and .modal-xl (1140 px), .modal-fullscreen and responsive variants such as .modal-fullscreen-md-down, vertical centering, a body that scrolls on its own with .modal-dialog-scrollable, backdrop: "static" to ignore backdrop clicks, page scroll lock with scrollbar width compensation, and show, shown, hide, hidden and hidePrevented events where hide can be canceled. The docs state that only one modal at a time is supported and nested modals are not, and they recommend placing modal markup at the top level of the page. There is no function that builds a dialog from options; the modal works on markup already in the page.
Choose it if your project already loads Bootstrap’s JavaScript.
CoreUI modal
Our own entry. The CoreUI modal is part of the free, MIT @coreui/coreui package. It is a fork of Bootstrap 5.3’s modal.js, and in our side-by-side tests it behaved identically to Bootstrap’s modal. It has the same sizes, responsive fullscreen, scrollable body, static backdrop and cancelable hide event, with .coreui event names and data-coreui-* attributes, and it inherits CoreUI’s themes and color modes. It also inherits the same limits: no nested modals (the docs keep Bootstrap’s statement), no non-modal mode beyond turning off the backdrop, and no way to create a dialog from options.
To be direct: the CoreUI modal has no functional advantage over the Bootstrap modal. Use it because the rest of your app is on CoreUI for Bootstrap and you want consistent styling and one dependency, not as a reason to switch.
Choose it if your app already runs on CoreUI for Bootstrap.
Which one fits your project
- Bootstrap or CoreUI project: keep the modal you already have. Add the native
<dialog>only for the rare stacked-dialog case, since neither supports nesting. - Your own design system: the native
<dialog>first; add Micromodal or a11y-dialog if you want trigger attributes and lifecycle events across older code. - Web components: Web Awesome Dialog, which gives you native behavior plus a ready header and footer.
FAQ
Do I still need a JavaScript modal library in 2026?
Often not. The native <dialog> with showModal() handles top-layer rendering, stacking, a non-modal mode and a cancelable close in every major browser. Libraries add styling, structure, size presets and conveniences such as page scroll lock.
Can I open a modal inside another modal?
With the native <dialog>, Micromodal (since 0.7.0) and a11y-dialog, yes. The Bootstrap and CoreUI docs state that nested modals are not supported.
Is the CoreUI modal different from the Bootstrap modal?
Not functionally. It is a fork of Bootstrap 5.3’s modal and behaved identically in our tests; the difference is CoreUI styling, themes and data-coreui-* attribute names. It is free under MIT in @coreui/coreui.
How do I close a dialog when the user clicks the backdrop?
Bootstrap and CoreUI do it by default (set backdrop: "static" to prevent it). Micromodal and a11y-dialog close on clicks on an overlay element carrying their close attribute. Web Awesome uses the light-dismiss attribute. The native <dialog> supports closedby="any" in Chrome, Edge and Firefox, but not yet in Safari.
Which modal options ship with styles?
Bootstrap, CoreUI and Web Awesome. Micromodal and a11y-dialog ship none by design, and the native <dialog> has only minimal browser defaults.