code/tamagui.dev/data/docs/core/animations-motion.mdx
Motion is a modern animation library built on the Web Animations API (WAAPI). It features a unique hybrid engine that combines JavaScript animations with native browser APIs to deliver high-performance, GPU-accelerated animations.
yarn add @tamagui/animations-motion motion
Add your animations to your Tamagui config:
import { createAnimations } from '@tamagui/animations-motion'
import { createTamagui } from 'tamagui'
export default createTamagui({
animations: createAnimations({
'75ms': { duration: 75 },
'100ms': { duration: 100 },
'200ms': { duration: 200 },
superBouncy: {
type: 'spring',
damping: 5,
mass: 0.7,
stiffness: 200,
},
bouncy: {
type: 'spring',
damping: 9,
mass: 0.9,
stiffness: 150,
},
}),
// ...
})
At runtime, the Motion driver uses the useAnimate() hook from the Motion
library to create animation scopes and orchestrate animations. It intelligently
batches style changes and only animates properties that have changed, optimizing
performance.
The driver leverages the Web Animations API (WAAPI) which runs animations on the compositor thread when possible, keeping animations smooth even when the main thread is busy.
Motion animations support both spring and tween (timing) animations:
{
type: 'spring',
damping: 10, // Higher = less bouncy
mass: 0.9, // Higher = more inertia
stiffness: 100, // Higher = faster
}
{
duration: 200, // Duration in milliseconds
}
You can add animation delays using the array syntax:
<Square transition={['bouncy', { delay: 200 }]} />
The delay is specified in milliseconds and is converted to seconds for Motion internally.
The Motion driver now works with Tamagui to bypasses all internal style changes to instead directly hand off directly to Motion.
The Web Animations API runs animations on the compositor thread when possible, keeping animations smooth even when the main thread is busy. This provides off-thread performance comparable to Reanimated, but for web-only applications.
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: {
type: 'spring',
damping: 10,
stiffness: 100,
},
})
// animations.native.ts
import { createAnimations } from '@tamagui/animations-reanimated'
export const animations = createAnimations({
bouncy: {
type: 'spring',
damping: 10,
stiffness: 100,
},
})
Then import without the extension:
import { animations } from './animations'
Your bundler will automatically pick the right file based on the platform.