
Sonner & Vaul
手感细腻的提示和抽屉组件开源
关于 Sonner & Vaul
Sonner 和 Vaul 是设计工程师 Emil Kowalski 写的两个 React 开源组件:Sonner 负责弹出提示(toast),Vaul 负责从屏幕边缘拉出的抽屉。两者都用 MIT 许可证,免费使用,以动效和手势手感见长。截至 2026-10-25,两者的处境已经分开:Sonner 的最新版本是 2026-08-10 发布的 2.0.8,仍在维护;Vaul 的 README 自 2025-10-04 起写明“不再维护”,最后一个版本是 2024-12-14 的 1.1.2。shadcn/ui 的 Radix 版本仍然用它们,但新项目默认的 Base UI 版本已经换成 Base UI 自带的提示和抽屉组件。

它是什么
Sonner 是一个 React 弹出提示组件。应用里放一个 <Toaster />,然后在任何地方调用 toast('保存成功'),屏幕角落就会弹出一条提示;多条提示会叠成一摞,鼠标移上去会展开,手指或鼠标一划就能关掉。仓库简介称它是“有主见的”提示组件,意思是默认样式和交互已经定好,开箱即用。
Vaul 是一个 React 抽屉组件,也就是手机上常见的、从屏幕底部拉上来、可以往下拖动关闭的面板。作者在介绍博客里说,做它是想在网页上还原 iOS 原生 Sheet 的手感;它建立在 Radix 的 Dialog 原语之上,焦点管理和无障碍由 Radix 处理,接口写法也和 Radix 保持一致。
两个库都出自 Emil Kowalski 之手,作者网站上的头衔是设计工程师。作者还开设了付费动效课程 animations.dev,两个库的文档页顶部都挂着另一门新课 aiforui.dev 的报名横幅。
截至 2026-10-25,Sonner 仓库有 13,080 个星标、468 个分叉,有 GitHub 账号的贡献者约 88 人;Vaul 仓库有 8,654 个星标,有 GitHub 账号的贡献者约 42 人(均按 GitHub API 统计)。两者的许可证都是 MIT,没有付费版,也没有托管服务。
一个有主见的 React 提示组件。
核心能力
叠放动画。Sonner 的招牌是多条提示叠成一摞的效果:后面的提示按序号往上错开、逐级缩小,制造出纵深感。作者在博客里说,这种叠放动画以前有公司做过,但从没开源,Sonner 一发布就因为这个动画走红。实现上用的是可以中途改变目标的 CSS 过渡,而不是关键帧动画,所以连续快速弹出好几条时,旧提示会平滑挪到新位置,不会跳。
按速度判断的滑动关闭。滑动关闭不要求拖过固定距离:如果划得够快,哪怕距离很短也会关闭。作者在博客里公开了判定方法:拖动距离除以耗时得到速度,超过阈值就移除。
常用类型齐全。toast() 支持成功、错误、加载中、带操作按钮、带取消按钮几种样式;toast.promise 会先显示加载状态,等异步任务成功或失败后自动更新为结果;也可以传入自己的 JSX,或者用无样式(headless)模式只保留行为、外观完全自定义。默认显示 4 秒,可以按条修改。
位置和布局可调。<Toaster /> 支持左上、上中、右上、左下、下中、右下六个位置;默认最多同时显示 3 条,可以改成更多,也可以设为始终展开。桌面端默认距屏幕边缘 32 像素,屏幕宽度小于 600 像素时改用 16 像素的移动端间距。2025-08-03 发布的 2.0.7 起支持在同一页面放多个 Toaster,用 id 把提示指向不同区域。
无障碍和细节。默认快捷键 ⌥/Alt + T 可以把焦点移到提示区;2.0.8 加入了自定义 aria 标签;支持从右到左的语言方向;样式表里有针对“减少动态效果”系统设置的规则。
体积小、零依赖。截至 2026-10-25,Bundlephobia 显示 2.0.8 压缩后约 34.1 KB、gzip 后约 9.4 KB,运行时没有依赖,只要求项目里有 React 18 或 19。
Vaul 的手势。Vaul 的拖动带动量,轻轻一甩就能关上;在已经滚到顶部时继续往上拉,抽屉会逐渐“变重”,模拟真实物体的阻尼。抽屉内部可以滚动,只有滚到顶端才允许拖动;作者还加了 100 毫秒的缓冲,防止快速滚动时误关。它还支持停靠点(snap points),以及把页面背景缩小成另一层卡片的效果。
给 AI 编程助手的说明。截至 2026-10-25,Sonner 的 README 提供了一个名为 ask-sonner 的技能包,可以装进支持技能的 AI 编程工具里,让工具协助接入和排查 Sonner。
适合谁 / 不适合谁
适合:
用 React 写产品、想要一个默认就好看的提示组件的团队。Sonner 两行代码就能用,默认动效和手势已经调好,不需要设计师再出规范。
在用 shadcn/ui Radix 版本的项目。shadcn/ui 的 Radix 版 Toast 页面写明旧组件已弃用、请改用 sonner 组件,Radix 版 Drawer 页面写明它构建在 Vaul 之上;这类项目里的 Sonner 和 Vaul 通常已经在依赖里了。
想学动效实现的前端工程师。作者把两个组件的实现思路写成了公开博客,从叠放算法、可中断过渡到滑动速度判定都有代码,适合当作学习材料。
不适合:
需要长期依赖抽屉组件的新项目。Vaul 的 README 自 2025-10-04 起写明不再维护,作者说近期不会回来;截至 2026-10-25,仓库还有 135 个未关闭的问题和 27 个未合并的拉取请求。
不用 React 的项目。两者都是 React 专用组件,Vue、Svelte 或原生 JavaScript 项目需要找对应生态的库。
需要通知中心、消息持久化或推送的场景。Sonner 只负责界面上的临时提示,不保存历史,也不处理服务端推送。
要求界面风格和默认样式差别很大的团队。文档自己说,大幅定制时推荐用无样式模式;如果用类名覆盖默认样式,需要加 !important。
和同类比
和 react-hot-toast、React-Toastify 比。这两个也是 MIT 许可的 React 提示库,截至 2026-10-25,GitHub 星标分别为 10,988 和 13,444。按 npm 官方下载接口统计,2026-09-28 至 2026-10-04 这一周,sonner 下载约 6,350 万次,react-hot-toast 约 449 万次,React-Toastify 约 461 万次。下载量包含持续集成和依赖链带来的自动安装,只能看相对规模,不能当作用户数。shadcn/ui Radix 版本用 Sonner 作为提示组件。
和 Base UI Toast 比。Base UI 是一个无样式的 React 组件库,MIT 许可,截至 2026-10-25 文档显示版本为 1.9.0。它的 Toast 同样支持叠放、滑动关闭、Promise 和操作按钮,并提供全局管理器。2026 年 7 月 shadcn/ui 把 Base UI 设为新项目默认,同时为 Base UI 版本推出了基于 Base UI 原语的新 Toast。
Vaul 和 Base UI Drawer 比。Base UI Drawer 支持停靠点、嵌套抽屉、虚拟键盘感知、从边缘滑动打开和背景缩进效果,覆盖了 Vaul 的主要能力,而且仍在活跃维护。shadcn/ui 的 Base UI 版 Drawer 页面写明组件已从 Vaul 换成 Base UI,并提供迁移指南。
上手路径
第一步,安装。在项目里运行 pnpm i sonner(npm、yarn 也可以)。要求项目使用 React 18 或 19。
第二步,放置 Toaster。把 <Toaster /> 放在应用根部,比如 Next.js 的 layout.tsx 里;文档说明它可以放在服务端组件中。需要深色模式时,把主题库(如 next-themes)给出的当前主题传给 theme 属性。
第三步,调用。在任意位置 import { toast } from 'sonner',调用 toast('已保存');成功和失败分别用 toast.success、toast.error,异步操作用 toast.promise 传入 Promise 和三种状态的文字。
第四步,调整外观。小改动用 toastOptions 统一设置样式或类名;大改动用无样式模式自己写 JSX。用 Tailwind 覆盖默认样式时要加 !important,文档对此有说明。
如果用 shadcn/ui:Radix 版本里用 shadcn 的 add 命令添加 sonner 组件即可;Base UI 版本的 Toast 已经是另一套实现,通过 useToastManager 拿到管理器后调用 toastManager.add,和 Sonner 的 toast() 不同,不要混用两套文档。
Vaul 上手:运行 pnpm i vaul,按 Drawer.Root、Drawer.Trigger、Drawer.Portal、Drawer.Overlay、Drawer.Content 的结构组合即可,写法和 Radix Dialog 一样。作者在博客里提到,原先在用的抽屉在输入框上出过问题。
定价与许可证
完全免费。截至 2026-10-25,Sonner 和 Vaul 都以 MIT 许可证发布在 npm 上,没有付费版、专业版或托管服务,商业项目可以直接使用,只需保留许可证声明。
许可证来源。Sonner 的 LICENSE.md 由提交 2f6f087(提交信息为 add license)于 2023-02-23 19:06 (UTC+8) 加入,内容为 MIT,此后没有改动过;Vaul 的许可证文件在 2023-07-23 21:44 (UTC+8) 的首个提交 7ff134e 中就已存在,同样是 MIT,之后也没有改动。
作者的收入来源与两个库无关:作者开设付费动效课程 animations.dev,截至 2026-10-25 课程页称已有 13,000 多名设计师和工程师学过(官方自述),下一期报名于 2026-11-10 开放。
隐性成本。Vaul 停止维护后,问题需要使用者自行修复或迁移到其他组件。
风险与局限
Vaul 已停止维护。README 顶部写明:这个仓库不再维护,作者也许以后会回来,但近期不会;它一直是业余项目,作者现在没有时间也没有意愿投入。这段说明由 2025-10-04 03:25 (UTC+8) 的提交 3e97aac 加入。截至 2026-10-25,Vaul 的文档站首页没有同样的提示。
Sonner 的更新。2.0.7 发布于 2025-08-03,2.0.8 发布于 2026-08-10;2.0.8 的修复中包括作者自己的“修复一批已报告问题”。截至 2026-10-25,仓库还有 40 个未关闭的问题。
单人维护的风险。两个库的设计和主要提交都来自作者一人,作者自己在 Vaul 的说明里把它定性为业余项目。
生态在迁移。shadcn/ui 从 2026 年 7 月起把 Base UI 设为新项目默认,Base UI 版本的提示和抽屉都不再使用 Sonner 和 Vaul。Radix 版本仍受支持。
定制方式。用类名覆盖默认样式时需要 !important;文档建议大幅定制直接用无样式模式,这意味着要自己写完整的外观。
来龙去脉
2023-02-23,Sonner 仓库创建,当天加入 MIT 许可证。作者在博客中回忆,当时 React 提示组件已经很多,起名时刻意避开 react-toast 这类功能性名字,从法语里挑了 sonner 这个词,意思是“响铃”。2023 年 3 月起陆续发布 0.x 版本,叠放动画的演示视频在社交媒体上传开。
2023-07-23,Vaul 的首个提交出现。作者在博客里说,当时所在的 Vercel 团队已经在用类似的抽屉,但缺少拖动关闭,输入框也有问题,于是从零写了一个并开源;Vaul 在 2023-07-27 发布 0.1 版。
2023-09-20,Sonner 发布 1.0.0,加入了考虑滑动速度的关闭判定和文档站。之后 shadcn/ui 把 Sonner 作为推荐的提示组件,Drawer 组件也构建在 Vaul 之上,两个库随 shadcn/ui 的模板进入大量项目。
2024-09-27,Vaul 发布 1.0.0 和新文档站;2024-12-14 发布 1.1.2,此后再没有新版本。
2025-02-19,Sonner 发布 2.0.0,发布说明称主要是错误修复。2025 年间 2.0.x 陆续加入多 Toaster 和测试 id 等功能。
2025-10-04,作者在 Vaul 的 README 里写明不再维护。
2026 年 7 月,shadcn/ui 宣布 Base UI 成为新项目默认,并为 Base UI 版本推出新的 Toast;Base UI 版 Drawer 也从 Vaul 换成了 Base UI 实现。2026-08-10,Sonner 发布 2.0.8,合入了累积一年的修复。作者博客称 Sonner 每周下载超过 4,000 万次,Cursor、X、OpenAI 等公司在用(作者自述,博客未标日期)。
我们的判断
Sonner 和 Vaul 的特点是:Sonner 运行时零依赖、两行代码接入,默认带叠放动画和按速度判定的滑动关闭,截至 2026-10-25 仍有维护;Vaul 还原 iOS Sheet 的拖动手感;作者把两者的实现细节写成了公开博客。
它们的限制:Vaul 自 2025-10-04 起写明不再维护;Sonner 2.0.7 和 2.0.8 相隔一年,两个库主要由作者一人维护;shadcn/ui 的 Base UI 版本已改用 Base UI 自带的提示和抽屉组件;大幅定制需要无样式模式或 !important。
亮点
Sonner 是一个消息提示组件,Vaul 是一个抽屉组件,两者合起来,是关于“交互界面该是什么手感”最好的一堂短课。Emil Kowalski 在时机、堆叠、滑动物理和减弱动效模式上的用心程度,是大多数产品团队从未达到的。
这两个库体积小、依赖少,被大量现代 React 应用使用,shadcn/ui 默认提供的组件里也有它们。他写的关于动画的文章,和代码一样有价值。
Sonner(提示)和 Vaul(抽屉)是体积小、依赖少的库,shadcn/ui 自带的组件默认就在用。
资料来源
官方
- emilkowalski/sonner: An opinionated toast component for React (GitHub) · 访问于 2026 年 10 月 25 日
- Releases · emilkowalski/sonner (GitHub) · 访问于 2026 年 10 月 25 日
- add license · emilkowalski/sonner@2f6f087 (GitHub) · 访问于 2026 年 10 月 25 日
- sonner package.json (GitHub) · 访问于 2026 年 10 月 25 日
- Getting Started – Sonner · 访问于 2026 年 10 月 25 日
- Toast – Sonner · 访问于 2026 年 10 月 25 日
- Toaster – Sonner · 访问于 2026 年 10 月 25 日
- Styling – Sonner · 访问于 2026 年 10 月 25 日
- sonner src/styles.css (GitHub) · 访问于 2026 年 10 月 25 日
- Building a toast component – Emil Kowalski · 访问于 2026 年 10 月 25 日
- emilkowalski/vaul: A drawer component for React (GitHub) · 访问于 2026 年 10 月 25 日
- Explain maintenance · emilkowalski/vaul@3e97aac (GitHub) · 访问于 2026 年 10 月 25 日
- Releases · emilkowalski/vaul (GitHub) · 访问于 2026 年 10 月 25 日
- Getting Started – Vaul · 访问于 2026 年 10 月 25 日
- Building a drawer component – Emil Kowalski · 访问于 2026 年 10 月 25 日
媒体与第三方
- sonner@2.0.8 – Bundlephobia · 访问于 2026 年 10 月 25 日
- Toast · Base UI · 访问于 2026 年 10 月 25 日
- Drawer · Base UI · 访问于 2026 年 10 月 25 日
相关产品
- npm downloads API: sonner, 2026-09-28 to 2026-10-04 · 访问于 2026 年 10 月 25 日
- npm downloads API: vaul, 2026-09-28 to 2026-10-04 · 访问于 2026 年 10 月 25 日
- July 2026 - Base UI as the Default - shadcn/ui · 访问于 2026 年 10 月 25 日
- July 2026 - Toast - shadcn/ui · 访问于 2026 年 10 月 25 日
- Toast (Radix UI) - shadcn/ui · 访问于 2026 年 10 月 25 日
- Drawer (Radix UI) - shadcn/ui · 访问于 2026 年 10 月 25 日
- Drawer (Base UI) - shadcn/ui · 访问于 2026 年 10 月 25 日
- timolins/react-hot-toast (GitHub) · 访问于 2026 年 10 月 25 日
- fkhadra/react-toastify (GitHub) · 访问于 2026 年 10 月 25 日
- animations.dev – Emil Kowalski · 访问于 2026 年 10 月 25 日