Best Vue Modal and Dialog Components (2026): 7 Libraries Compared
PrimeVue Dialog is the most complete Vue dialog, with a confirm service, dynamic dialogs opened from code, dragging, maximizing and positions on every edge, but PrimeVue 5 is no longer MIT. Quasar QDialog is the strongest MIT choice for application flows: a dialog plugin you can call even outside components, unlimited nesting and a non-modal mode. Element Plus ElDialog is the pick when you want dragging, a before-close hook and promise-based ElMessageBox.confirm() in one MIT package. Naive UI NModal covers similar ground with useModal() and useDialog(). Vuetify VDialog and CoreUI CModal suit declarative dialogs in their own design systems, with nesting in Vuetify and one-prop responsive fullscreen in CoreUI.
How we compared
We compared seven Vue 3 dialog components in October 2026 on a 23-feature checklist covering behaviour, layout and API, using primevue 5.0.4, quasar 2.35.2, element-plus 2.14.7, naive-ui 2.45.3, vuetify 4.3.1, ant-design-vue 4.2.6 and @coreui/vue 5.10.1.
Facts come from vendor docs, published source code and public demos. A ❌ for a competitor means its own docs state the limit; — means we found no evidence either way, not that the feature is missing. The CoreUI row follows the same rules, from our own docs and source.
The comparison at a glance
✅ built in and documented · Partial = part of the behaviour, a demo to copy, or a separate component · ❌ confirmed absent (vendor docs, or for CoreUI our own source) · — no data
| Library | Licence | Sizes | Fullscreen | Positions | Scroll inside | Nested dialogs | Open from code | Confirm dialog | Draggable | Non-modal mode | Lazy rendering | SSR documented |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PrimeVue Dialog (5.0.4) | PrimeUI License | ✅ (breakpoints) | ✅ (maximizable) | ✅ | ✅ | Partial | ✅ (DialogService) | ✅ (ConfirmDialog) | ✅ | ✅ | — | ✅ (Nuxt module) |
| Quasar QDialog (2.35.2) | MIT | ✅ | ✅ (maximized) | ✅ | ✅ | ✅ | ✅ ($q.dialog) | ✅ | — | ✅ | Partial | ✅ |
| Element Plus ElDialog (2.14.7) | MIT | ✅ (width) | ✅ | ✅ | — | ✅ | Partial (ElMessageBox only) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Naive UI NModal (2.45.3) | MIT | Partial (style) | — | ✅ | ✅ | Partial | ✅ (useModal) | ✅ (useDialog) | ✅ | ✅ | ✅ | ✅ |
| Vuetify VDialog (4.3.1) | MIT | ✅ | ✅ | Partial | ✅ | ✅ | — | — | — | — | ✅ | ✅ |
| Ant Design Vue Modal (4.2.6) | MIT | ✅ (width) | Partial (demo) | ✅ | Partial | — | ✅ (Modal.confirm) | ✅ | Partial (vueuse) | — | ✅ | Partial |
| CoreUI CModal (@coreui/vue 5.10.1) | MIT | ✅ | ✅ (below breakpoint) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | — |
The libraries, one by one
PrimeVue Dialog
PrimeVue Dialog has the widest layout options of any Vue dialog: position on every edge and corner, breakpoints for responsive widths, maximizable, inside scrolling with a fixed header and footer, and draggable (on by default) with keepInViewport. It is non-modal unless you set modal. DialogService with useDialog().open() opens any component as a dialog, including lazily loaded ones, and ConfirmDialog with useConfirm() handles confirmations, alongside ConfirmPopup for inline ones. The #container slot gives you a headless mode, and an official Nuxt module covers SSR. The real decision is the licence (see below).
Choose it if you want the richest dialog toolkit and the PrimeUI licence works for you.
Quasar QDialog
Quasar QDialog is built for apps: the Dialog plugin (Dialog.create(), $q.dialog()) works outside Vue components and can render your own component through useDialogPluginComponent, the docs promise an “infinite number of depth levels” for dialogs in dialogs, and seamless gives a non-modal panel. It also has persistent with a shake animation, five positions, maximized, full-width and full-height sizing, and any Quasar transition for showing and hiding. Content is mounted only while the dialog is open.
Choose it if you build with Quasar or need dialogs triggered from stores and services.
Element Plus ElDialog
Element Plus ElDialog offers draggable with overflow, fullscreen, align-center, a width that defaults to 50%, a before-close(done) hook that can cancel closing, modal-penetrable (2.10.5) for a clickable page behind, append-to for a custom container, lazy rendering until first open plus destroy-on-close, and a transition prop (2.10.5). Confirmations go through ElMessageBox.confirm(), which returns a Promise; alert and prompt work the same way. Nesting works with append-to-body on the inner dialog, though the docs do not recommend it, and the SSR guide covers ElDialog’s Teleport.
Choose it if you want a capable MIT dialog with dragging and promise-based confirms.
Naive UI NModal
Naive UI NModal comes as card and dialog presets. useModal().create() (2.38.0) and useDialog() open dialogs from code, and createDiscreteApi does so outside setup. It supports draggable (2.41.0) with bounds, fixed positioning, a scrollable content area with fixed header and footer in the card preset, show-mask=false for a floating panel, display-directive to control mounting, and a to prop for the target container. Width is set through style, and the library has an SSR guide covering Nuxt.
Choose it if you already use Naive UI and want imperative dialogs with dragging.
Vuetify VDialog
Vuetify VDialog supports nesting (“Dialogs can be nested”), fullscreen (recommended on mobile), scrollable, width, max-width and height, persistent, custom transitions including top and bottom variants, attach for a custom container and eager rendering. Content is rendered lazily on first open by default. Dialogs are always declared in the template, through an activator or v-model, and the docs suggest filling them with VCard for title, text and actions. Nuxt 3 setup is documented for the whole library.
Choose it if you are on Vuetify and need nested or fullscreen dialogs.
Ant Design Vue Modal
Ant Design Vue Modal brings antd’s API to Vue: Modal.confirm, info, success, warning and error, Modal.useModal(), Promise-aware onOk, centered, width, getContainer, forceRender and destroyOnClose. Dragging and full screen are demos (useDraggable from @vueuse/core, and custom styles). The package has not had a stable release since November 2024.
Choose it if you maintain an existing antdv app.
CoreUI CModal for Vue
Our own entry. CoreUI Modal for Vue is free (MIT) in @coreui/vue. It offers backdrop="static" with a close-prevented event, a scrollable body, sm, lg and xl sizes, fullscreen always or only below a breakpoint (sm to xxl), vertical centering, teleport (off by default) with a custom container, unmountOnClose, and an animation you can restyle with SCSS variables or switch off with transition.
What it lacks, from our own docs: only one modal can be open at a time, there is no API to open a modal from code, no confirm dialog, no non-modal mode and no dragging, and SSR with Nuxt is not covered in the docs. Commercial components such as Smart Table are in CoreUI PRO.
Choose it if your Vue app uses CoreUI or Bootstrap styling and declarative dialogs are enough.
The 2026 picture
- PrimeVue 5 uses the PrimeUI License since 15 July 2026: free only under the Community thresholds (under $1M revenue, five developers, ten employees, $3M funding), otherwise $599 per developer until 31 December 2026, then $799. PrimeVue 4.5.5 is still MIT.
- Ant Design Vue has not published a stable release since 4.2.6 on 11 November 2024.
- Vuetify 4 (4.3.1) is current;
v3-stablecontinues as 3.13.7.
FAQ
How do I open a confirm dialog from code in Vue?
Use ElMessageBox.confirm() in Element Plus, useConfirm().require() with ConfirmDialog in PrimeVue, $q.dialog() in Quasar, useDialog() in Naive UI, or Modal.confirm() in Ant Design Vue.
Which Vue modal libraries support nested dialogs?
Quasar (“infinite number of depth levels”), Vuetify (“Dialogs can be nested”) and Element Plus (with append-to-body on the inner dialog, though its docs do not recommend nesting). CoreUI supports one modal at a time.
Which Vue dialogs can be dragged?
PrimeVue (draggable, on by default), Element Plus (draggable, with overflow) and Naive UI (draggable, since 2.41.0). Ant Design Vue shows dragging with @vueuse/core in a demo. PrimeVue drags by the header and keeps the dialog in view with keepInViewport, minX and minY.
Can I open a Vue dialog outside a component, from a store or service?
Yes in Quasar, whose Dialog plugin works outside Vue components, and in Naive UI through createDiscreteApi. Element Plus’s ElMessageBox can also be imported and called directly.
Is PrimeVue still free?
PrimeVue 4.x is MIT. PrimeVue 5.x uses the PrimeUI License, which is free only for small companies under the Community thresholds and paid per developer otherwise.