Motion System: Raycast
Category: macOS Launcher / Productivity Tool Spring-native motion that makes the fastest app on your Mac feel even faster than it is.
Motion Philosophy
Raycast's motion is designed to make the application feel faster than its actual response time. The core trick is spring physics on entrance: the main window doesn't just appear, it arrives with a spring that front-loads the motion so heavily that the window seems to have been there before you summoned it. This perceptual sleight-of-hand — borrowed from Spotlight but tuned more aggressively — is the single most important motion decision in the product. Everything else is in service of not betraying that promise.
The system is built for keyboard users who never touch the mouse while Raycast is open. That constraint drives two rules: hover states and focus highlight transitions must be instant (0ms), because a highlight that lags behind arrow-key presses creates a disconnect between intent and feedback that destroys the feeling of control. The second rule is that list items stagger on population, not on navigation. When you type a query and results arrive, items stagger in at 12ms intervals to give the eye a reading path. When you press the down arrow, the highlight moves at 0ms — the stagger never fires again.
Sound design and motion are understood as partners here. The satisfying snap of Raycast's window appearance is inseparable from its spring config. The motion is deliberately slightly overshoot-free but very fast, targeting a feel that reads as "macOS-native but tighter." It is conspicuously more premium than Spotlight, and premium in this context means faster and more confident, not slower and more elaborate.
Duration Scale
| Token | Value | Use |
|---|---|---|
| instant | 0ms | Keyboard navigation highlight, focus ring, selection state, checkbox state |
| micro | 50ms | Icon color transitions, badge updates, active state on list items |
| fast | 100ms | Tooltip appearance, context action bar slide-in, secondary pane entrance |
| default | 130ms | Command list item entrance (non-spring), section headers, empty state |
| medium | 160ms | Detail panel sliding in, settings panel appearance |
| slow | 200ms | Onboarding walkthrough steps, large view transitions |
| window | spring | Main window appearance/disappearance, search result population |
Easing
| Token | Curve | Use |
|---|---|---|
| ease-out | cubic-bezier(0.16, 1, 0.3, 1) | Elements entering from a direction |
| ease-in | cubic-bezier(0.7, 0, 0.84, 0) | Elements exiting — accelerates away quickly |
| ease-in-out | cubic-bezier(0.45, 0, 0.55, 1) | Internal repositioning, list reordering |
| spring | See spring configs | Window, search results, action panels |
Raycast's ease-out is identical to Linear's — both target the same native-app aesthetic where elements appear to arrive rather than travel. The distinction in Raycast is that this curve is applied even more broadly, including to the window-level spring.
Spring Configs (Framer Motion)
- Window: stiffness: 550, damping: 36, mass: 0.8 — main window entrance; fast arrival, clean stop with no bounce
- Results: stiffness: 480, damping: 34, mass: 0.9 — search result list populating after query
- Panel: stiffness: 400, damping: 32, mass: 1 — detail and action panels sliding in from the right
- Micro: stiffness: 800, damping: 44, mass: 0.5 — icon scale on hover, action button press
All configs are critically damped or above. The Window config in particular must never visibly overshoot — a bouncing launcher window would violate the native macOS contract.
Stagger Patterns
- Search results on query: 12ms between each item, starts immediately on first result
- Command list initial load: 15ms between items, fires once on mount
- Action panel items: 10ms between each action, fires on panel open
- Extension grid icons: 25ms between each icon on Settings > Extensions load
Stagger fires only on initial population. Re-querying resets and re-staggers only newly appearing items; items that persist from the previous query do not re-animate.
Enter / Exit Patterns
Window Spring (main Raycast window)
enter: opacity 0→1, scale 0.96→1, translateY -8px→0, spring: Window config
exit: opacity 1→0, scale 1→0.94, translateY 0→8px, duration: fast (100ms), ease: ease-in
The exit is duration-based, not spring-based — closing should be fast and clean, not physically simulated.
Result List Item Entrance
enter: opacity 0→1, translateY 6px→0, spring: Results config, staggered 12ms
(no exit animation — items are removed immediately)
Detail / Action Panel (slides from right)
enter: translateX 100%→0, spring: Panel config
exit: translateX 0→100%, duration: fast (100ms), ease: ease-in
Tooltip
enter: opacity 0→1, scale 0.95→1, duration: micro (50ms), ease: ease-out
exit: opacity 1→0, duration: instant (0ms)
Empty State
enter: opacity 0→1, translateY 12px→0, duration: default (130ms), ease: ease-out
exit: opacity 1→0, duration: micro (50ms), ease: ease-in
Interaction States
- Keyboard navigation highlight: 0ms. The selected row background updates synchronously with the keypress event. Any lag here destroys the feeling of control.
- Hover highlight: 0ms via CSS background transition. Mouse users get the same instantaneous feedback as keyboard users.
- Press/Active: scale(0.95) on action buttons with Micro spring, releases on pointer-up. List items do not scale on press — only explicit button elements.
- Focus: Focus ring at 0ms via CSS outline. Never animated.
- Loading / fetching: Subtle shimmer on the search input border, CSS keyframe animation at 1000ms linear. Spinner appears in the input trailing slot at 16px, 700ms linear rotation. The list never shows skeletons — results appear when ready with stagger entrance.
- Pinned / favorited toggle: Icon morphs with Micro spring, 50ms fill color transition. Feels mechanical.
Rules
- Respect
prefers-reduced-motion. All spring and duration animations collapse to 0ms. Window appearance becomes instant. - Keyboard navigation must never be delayed. The 0ms rule on highlight transitions is absolute.
- The main window spring config is the product's signature motion — treat it with care. Never increase the damping to the point where the arrival loses its snap.
- Exit animations are always shorter than enter animations and often omitted entirely. Raycast disappears; it does not leave.