Motion Driver

High-performance web animations with WAAPI

Motion combines JavaScript animation controls with the Web Animations API for smooth, browser-native animation.

Installation

yarn add @tamagui/animations-motion motion

Configuration

Add your animations to your Tamagui config:

import { createAnimations } from '@tamagui/animations-motion'
import { createTamagui } from 'tamagui'
export default createTamagui({
animations: createAnimations({
quick: { duration: 220, bounce: 0.3 },
bouncy: { duration: 400, bounce: 0.5 },
superBouncy: { duration: 400, bounce: 0.75 },
}),
// ...
})

The config format is the same for all four drivers, so a name means the same motion whichever driver renders it. There is no need for '200ms'-style entries any more: a duration is CSS, so transition="200ms" works with nothing configured.

How it works

At runtime, the Motion driver uses the useAnimate() hook from the Motion library to batch style changes and animate only what changed. It runs through the Web Animations API (WAAPI), which animates on the compositor thread when possible, keeping animations smooth even when the main thread is busy.

Animation configuration

Motion animations support both spring and timing animations:

Spring animations

{
duration: 400, // the spring's undamped period, in milliseconds
bounce: 0.5, // 0 is critically damped, toward 1 is loose, negative is sluggish
}

stiffness, damping, and mass still work for a config already tuned against them, and velocity, overshootClamping, and the rest thresholds pass through.

Timing animations

{
type: 'timing',
duration: 200, // Duration in milliseconds
easing: 'ease-out', // any css timing function
}

A plain CSS string means the same thing: '200ms ease-out'.

Delay

<Square transition={{ preset: 'bouncy', delay: 200 }} />

The delay is specified in milliseconds and is converted to seconds for Motion internally.

Highlights

Zero re-renders

The Motion driver bypasses internal style recalculations and hands off updates directly to Motion.

WAAPI performance

Off-thread performance comparable to Reanimated, but for web-only applications.

Platform-specific configuration

For cross-platform apps, use Motion on web and Reanimated on native:

// animations.ts (web)
import { createAnimations } from '@tamagui/animations-motion'
export const animations = createAnimations({
bouncy: { duration: 400, bounce: 0.5 },
})
// animations.native.ts
import { createAnimations } from '@tamagui/animations-reanimated'
export const animations = createAnimations({
bouncy: { duration: 400, bounce: 0.5 },
})

Then import without the extension:

import { animations } from './animations'

Your bundler will automatically pick the right file based on the platform.

See also