dialog-polyfill

A lightweight, dependency-free polyfill that brings native <dialog> element behavior — modals, backdrops, and method="dialog" forms — to browsers without built-in support.

Library
npm
v0.5.6
2,458stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
54/100Fair
Development Activity24
Maintenance20
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
60/100Good
Architecture68
Code Quality58
Innovation48
Learning Curve65

dialog-polyfill is Google Chrome’s official polyfill for the HTML <dialog> element, giving browsers without native support the same modal and non-modal dialog behavior, backdrop rendering, and <form method=“dialog”> handling that the spec defines. It works by upgrading <dialog> elements in place — binding show(), showModal(), and close(), tracking the open attribute with a MutationObserver, and inserting a synthetic backdrop element — so application code can call the same dialog API regardless of whether the browser implements it natively.

Because it patches global behavior only when window.HTMLDialogElement is undefined, the polyfill gets out of the way entirely in modern browsers while still providing consistent focus trapping, Escape-to-cancel, and z-index stacking across multiple open dialogs in older ones. It ships as both a UMD bundle and an ES module, with hand-written TypeScript declarations, making it a drop-in dependency for any project that wants to use the native <dialog> element without waiting for full browser support.

What You Get

  • Full <dialog> API polyfill - show(), showModal(), and close() methods bound directly onto real <dialog> elements, matching native behavior and error semantics.
  • Modal focus & keyboard handling - capturing-phase focus and keydown listeners trap Tab navigation inside the top-most modal and close it on Escape, just like the native element.
  • Backdrop and stacking support - a synthetic .backdrop element and z-index stacking manager reproduce ::backdrop styling and correct layering for multiple open dialogs.
  • <form method=“dialog”> support - patches form submission so dialog-closing forms work the same whether or not the browser understands method=“dialog” natively.
  • UMD, ESM, and TypeScript builds - prebuilt dist/dialog-polyfill.js (UMD) and dist/dialog-polyfill.esm.js bundles plus hand-written index.d.ts declarations.

Common Use Cases

  • Cross-browser modal dialogs - Teams supporting older browsers use the polyfill so <dialog> behaves identically everywhere without branching their modal code.
  • Confirmation and settings dialogs - Developers use <form method=“dialog”> inside a polyfilled dialog to close it and report a return value on submit, without wiring up manual close handlers.
  • Design systems built on native <dialog> - Component libraries wrap the polyfill so their modal component works the same whether the browser ships native support or not.
  • Accessible modal implementations - Projects that want spec-correct focus trapping and Escape handling without hand-rolling their own dialog manager.

Under The Hood

Architecture The library is a single flat module built around a factory pattern: a dialogPolyfillInfo constructor upgrades individual <dialog> elements by binding show/showModal/close methods and installing a MutationObserver to track the open attribute, while a singleton DialogManager (dialogPolyfill.dm) maintains a pending-dialog stack and coordinates z-index stacking, a shared backdrop overlay, and capturing-phase keydown/focus listeners so only the top-most modal traps focus and responds to Escape. Global side effects — patching HTMLFormElement.prototype.submit, hijacking method=“dialog” form submission, and capturing form submitters via a document-level click listener — are installed once at module-load time, gated behind a check for window.HTMLDialogElement, which is the layer that would need to change if browser support assumptions shifted. A build step compiles this one source file into UMD and ESM bundles, so there’s no internal module boundary beyond what the problem itself requires.

Tech Stack Vanilla, dependency-free JavaScript with a hand-written CustomEvent shim for older IE, built via Rollup into dist/dialog-polyfill.js (UMD) and dist/dialog-polyfill.esm.js (ESM), plus a copied CSS file for the backdrop styling. devDependencies are limited to rollup, chai, mocha, and npm-run-all. It ships hand-authored index.d.ts type declarations covering both global (script-tag) and ESM default-export usage.

Code Quality The test suite is extensive, covering centering, stacking, backdrop interaction, form submission, focus trapping, and shadow DOM behavior, and includes teardown logic that closes dialogs between tests. It runs via Mocha/Chai loaded directly in browser fixture pages rather than headlessly, and there is no CI workflow in the repo, so the suite depends on a maintainer opening it manually. The core module throws descriptive errors matching native <dialog> failure semantics rather than failing silently, uses a consistent trailing-underscore convention for private members, and annotates nearly every function with Closure-style JSDoc types; there is no linter/formatter configuration and no TypeScript source, only hand-written declarations layered on top of plain JS.

What Makes It Unique The library faithfully polyfills genuinely tricky platform behavior — modal focus trapping, Escape-to-cancel, top-layer stacking, and backdrop click regions — using only MutationObservers, a synthetic z-index stacking manager, and capturing-phase listeners, with no framework dependency. Its handling of <form method=“dialog”> is unusually thorough, patching the method property’s getter/setter and HTMLFormElement.prototype.submit, and capturing the actual form submitter to reproduce return-value semantics browsers don’t otherwise expose consistently. This is a well-tested, standards-faithful polyfill rather than a novel architecture.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search