esc

Type to search...

The choice

Vaul (by Emil Kowalski, widely adopted at Vercel) is the modern answer for iOS style drawers in React. It's gesture driven, spring animated, accessible through Radix Dialog primitives, and polished to the point that using it feels closer to a native sheet than most web libraries manage. Bottom drawers with numeric snap points are its bread and butter.

swipe-bar aims at the adjacent problem. It's opinionated toward left, right, and bottom sidebars as peers, with multi instance support on the same edge, mouse and touch parity on desktop, and zero runtime dependencies. The feel is similar. The API and scope aren't.

Where each one sits

Vaul is a drawer primitive with a strong bottom sheet identity. You compose its controlled <Drawer> elements, pick snap points, and let Radix Dialog take care of accessibility.

swipe-bar is a sidebar system. Provider plus declarative components, same API for left, right, and bottom, and a context hook for programmatic control. Multi instance and mouse drag are first class concerns.

Feature by feature

Feature comparison between swipe-bar and Vaul

@luciodale/swipe-bar Sidebar system, zero deps, multi instance
Edge swipe to open
Yes
Drag to close with velocity commit
Yes
Spring physics
Yes
Left and right side drawers
Yes
Bottom sheet with snap points
mid anchor point
Multi instance per side
Yes
Mouse drag on desktop
Yes
Nested drawers
No
Accessibility
Yes
Runtime dependencies
Zero
Production track record
In production at a major bank, hundreds of thousands of users
Best fit
Side drawers, multi instance, PWAs. Themeable to match any native look, iOS included.
vaul iOS style drawer built on Radix Dialog
Edge swipe to open
Partial
Drag to close with velocity commit
Yes
Spring physics
Yes
Left and right side drawers
Available but bottom-first
Bottom sheet with snap points
numeric snap array, richer API
Multi instance per side
No
Mouse drag on desktop
No
Nested drawers
Yes
Accessibility
Radix Dialog backed
Runtime dependencies
Radix Dialog + primitives
Production track record
Adopted at Vercel, battle tested
Best fit
Bottom sheet with snap points, nested drawer flows.

Scope shape, not quality

Both libraries do gesture, physics, and accessibility well. The distinction is intent.

Vaul is optimized for the pattern iOS and Android users recognize as a bottom sheet: numeric snap points, nested push flows, dynamic content height, Radix a11y guarantees. It shines in mobile-first product UX where the bottom sheet is the primary surface.

swipe-bar is optimized for nav and settings drawers that live on the side, with the same gesture grammar also available on the bottom edge. Two settings drawers on the right edge, a nav on the left, and a bottom sheet is a shape swipe-bar models directly.

Multi instance, side by side

swipe-bar treats every sidebar as an independent instance identified by an id. Opening the nav drawer doesn't prevent opening a settings drawer from the same edge. The z-index and overlay stacking stay consistent because the provider orchestrates it centrally.

multi-instance.tsx
<SwipeBarLeft id="nav" isAbsolute>
  <Nav />
</SwipeBarLeft>

<SwipeBarLeft
  id="settings"
  isAbsolute
  swipeToOpen={false}
  swipeBarZIndex={70}
  overlayZIndex={65}
>
  <Settings />
</SwipeBarLeft>

Vaul treats a drawer as a dialog. Opening two at once on the same edge isn't a pattern the library models natively, and you'd end up coordinating state yourself.

Dependency weight

Vaul depends on Radix Dialog, which itself pulls a small tree of Radix primitives. That's a fair price for the accessibility guarantees and the existing Radix ecosystem familiarity. swipe-bar keeps the bundle lean and implements the accessibility pieces itself. If you already use Radix across your app, Vaul's extra weight is free. If you don't, swipe-bar's zero-dep claim is real.

When to pick Vaul

When to pick swipe-bar

Next steps