Skip to Content

Migrating from Sonner

web-haptics-toast is a standalone package: you install it once and get Sonner-compatible toasts plus a built-in haptics engine—no second dependency for vibration or presets.

It tracks Sonner’s public API (“toast(), <Toaster />, styling hooks). On top of that you get haptics (on by default) and an optional system layer for dedupe and dismiss reasons (Getting Started, Toaster).

Pick one path below.

Option A — Zero code changes (keep from 'sonner')

Install this package under the name sonner. Your imports and re-exports stay identical.

npm uninstall sonner && npm install sonner@npm:web-haptics-toast
  • Keep: import { Toaster, toast } from 'sonner'
  • Keep: import 'sonner/dist/styles.css' — the aliased package still exposes the same stylesheet path as Sonner.

Haptics run automatically on supported devices. To match old Sonner behavior (no vibration), use <Toaster haptics={false} /> once at your app root.

Option B — Use the web-haptics-toast package name

Useful when you want the dependency name to match the project and to avoid npm aliases.

Remove Sonner, add web-haptics-toast

npm uninstall sonner && npm install web-haptics-toast

Update imports

Replace every Sonner import:

- import { Toaster, toast } from 'sonner'; - import 'sonner/dist/styles.css'; + import { Toaster, toast } from 'web-haptics-toast'; + import 'web-haptics-toast/dist/styles.css';

Search your repo for from 'sonner', from "sonner", and sonner/dist/styles.css.

Optional: barrel files and tests

If you re-export from a shared notifications.ts (or similar), point that file at web-haptics-toast so the rest of the app keeps the same internal imports.

After you migrate

TopicNotes
Single packageComponents, CSS, and haptics (WebHaptics, presets) are all in web-haptics-toast—no extra haptics dependency.
HapticsDefault true on <Toaster />. Plain “toast('message') uses the default pattern when haptics are on; pass { haptics: false } on a call to skip. Haptics — hapticsDebug, hapticPatternMap, hapticsShowSwitch, triggerHaptic.
system propOpt-in dedupe (dedupeKey) and onClose with a dismissal reason. Off by default so Sonner-like behavior is unchanged. Getting Started, Toaster.
TypesPublished with the library; Sonner-shaped ToasterProps and toast options, plus haptics-related props.
StylingSame toastOptions, classNames, unstyled patterns as Sonner. Styling.

Checklist

  • Dependencies updated (alias or renamed package).
  • JS/TS imports and CSS import path updated if you chose Option B.
  • <Toaster /> still mounted once near the root.
  • Decide on haptics (true default vs haptics={false}).
  • If you need dedupe or onClose(reason), enable <Toaster system={{ … }} /> as in Getting Started.

If something behaves differently from Sonner after migration, open an issue on the GitHub repo  with a minimal repro.

Last updated on