My experience building a drawer component for React.
Summary
Vaul started because Apple's iOS sheet feels natural and the web had no real equivalent, and because the drawer Vercel was using lacked drag-to-dismiss. Emil built it on Radix Dialog so focus management and accessibility came for free, then kept a near-identical API so it would feel familiar. The write-up is honest about the hard parts. Dragging went laggy past roughly twenty list items because the drag position was set through an inherited CSS variable, which recalculated styles for every child, and writing the transform straight onto the element fixed it. Momentum, damping at the top and making a scrollable sheet draggable each get their own section.
View full writingGoes well with
emil-design-eng
The design-engineering house style behind Sonner and Vaul.
Emil's main skill. Mostly animation, with the UI-polish and component judgement that surrounds it: what to build, how far to push it, and when to stop.
npx skills add https://github.com/emilkowalski/skills
animate
Builds an animation from scratch, decisions in the order that matters.
Should it animate at all, what purpose, which tool, which properties, which curve and duration, how it interrupts, how it exits. Then writes the implementation.
npx skills add https://github.com/emilkowalski/skills --skill animate
review-animations
Reviews your motion strictly, against Emil's rules.
A production-critical pass over animation quality, timing and consistency in a diff. Pairs with improve-animations, which does the same for a whole codebase.
npx skills add https://github.com/emilkowalski/skills --skill review-animations