vue-sonner
An opinionated, customizable toast notification component for Vue 3 and Nuxt, ported from the React library Sonner.
Repository Health
Technical Analysis
Vue Sonner is a direct Vue port of the popular React toast library Sonner. It ships a single <Toaster /> component plus an imperative toast() API — toast.success(), toast.error(), toast.promise(), toast.custom() — so any component in a Vue 3 or Nuxt app can trigger a toast without prop drilling or a manual store.
Under the hood, a framework-agnostic Observer/pub-sub store holds the toast queue, and a useVueSonner() composable bridges it into Vue’s reactivity system. The library ships with sensible default styling (positions, themes, swipe-to-dismiss, stacking/expand behavior) but is fully overridable via an unstyled prop and a granular classes object, making it easy to restyle with Tailwind or a custom design system. A dedicated vue-sonner/nuxt module auto-registers the component and a $toast plugin for Nuxt 3/4 projects.
What You Get
- A
<Toaster />component and imperativetoast()API (toast.success,.error,.warning,.info,.loading,.promise,.custom,.dismiss) usable from any component - Promise-aware toasts that automatically transition through loading → success/error states based on the resolved value or thrown error
- Swipe-to-dismiss gestures with configurable
swipeDirectionsper toast position, plus stacked/expand toast layout - A first-class
vue-sonner/nuxtmodule that auto-registersToasterand injects a$toastplugin, with optional CSS opt-out - Full styling control via
unstyledmode and a per-partclassesobject (toast, title, description, action/cancel/close buttons) for Tailwind or custom design systems - TypeScript types for every public shape (
ToastT,ToasterProps,ExternalToast, etc.) shipped alongside the compiled library
Common Use Cases
- Showing loading → success/error feedback for an async form submission or API call via
toast.promise() - Registering the Nuxt module once and calling the injected
$toasthelper from any page or component in a Nuxt 3/4 app - Restyling toasts to match an existing Tailwind design system using the
unstyledprop andclassesobject instead of overriding default CSS - Showing an undo action toast (with an action button and callback) after a destructive operation like delete or archive
Under The Hood
Architecture
A central singleton Observer (src/packages/state.ts) maintains a subscriber list and toast array, framework-agnostic of Vue itself; the exported toast() function and its namespaced methods (success, error, promise, custom, dismiss, …) all funnel through this store. useVueSonner() (src/packages/hooks.ts) subscribes to the store inside a watchEffect and reconciles updates into a reactive activeToasts ref via nextTick, bridging the plain-JS store into Vue’s reactivity. Toaster.vue renders and groups active toasts by position and delegates per-toast presentation, swipe handling, and height measurement to Toast.vue. The Nuxt integration (src/module.ts, src/runtime/plugin.ts) is a thin wrapper: defineNuxtModule registers Toaster client-only and injects a $toast plugin, with an option to opt out of the shipped CSS — a clean separation between a framework-agnostic core store and Vue/Nuxt-specific presentation and wiring.
Tech Stack
Written in TypeScript against Vue 3.5 as a peer dependency, built with tsdown (a Rolldown-based bundler) for the primary ESM library output plus a separate UMD build (tsdown.config.umd.ts) for CDN/<script> usage. The Nuxt module is built separately via @nuxt/module-builder/@nuxt/kit. The repo is a pnpm workspace with the library, a Vite+UnoCSS demo/docs app, and a separate test/ Playwright workspace as distinct members. The published package has no runtime dependencies beyond Vue itself.
Code Quality
End-to-end tests live in a separate test/ Vite+Vue workspace driven by Playwright (test/e2e/vue.spec.ts, run via pnpm test:e2e --ui), but there are no unit tests for the core state.ts/hooks.ts logic in isolation. Every public shape (ToastT, ToasterProps, ExternalToast, etc.) has an explicit TypeScript interface, and the promise-toast flow in state.ts distinguishes HTTP-response failures, thrown Errors, and custom error callbacks with dedicated handling rather than swallowing errors. Two GitHub Actions workflows run on every push, but both only execute pnpm build:lib (plus a preview-package publish step) — neither runs the Playwright suite, so CI verifies the library still builds, not that its swipe/animation behavior still passes its own tests.
What Makes It Unique
Rather than designing a new toast model, Vue Sonner’s contribution is a faithful, idiomatic port of the React sonner library’s observer/pub-sub design and toast-type API surface into Vue’s Composition API, plus a genuine first-class Nuxt module (auto-registered component, client-only plugin, CSS opt-out) that its React counterpart has no equivalent for. It’s a solid adaptation layer rather than a novel toast-notification design.
Used by 5 apps in this directory
Hook0
Devops
Open-source Webhooks-as-a-Service: deliver events to your users with auto-retry, signed payloads, and a real-time subscriber dashboard — all without building the infrastructure yourself.
Litlyx
Analytics
Cookie-free, AI-powered web analytics you can self-host in 30 seconds with Docker.
massCode
Developer Tools · Productivity · Code Editors
A free, local-first developer workspace unifying snippets, notes, HTTP requests, calculations, drawings, and dev tools in one desktop app.
Scalar
Developer Tools
Beautiful, interactive OpenAPI documentation with a built-in offline-first API client and multi-language code generation — all in one open-source platform.
Sink
Bookmarks Archiving · Analytics
Serverless link shortener with real-time analytics, powered by Cloudflare