Animation Drivers

Choose and configure animation drivers for your platform

Tamagui supports four animation drivers across its platforms. Web supports CSS, Reanimated, and Motion. Native supports React Native and Reanimated.

Driver

Platform

Bundle Impact

Performance

Spring Physics

CSS

Web only

Lightest

Fast (CSS transitions)

Yes (sampled to linear())

React Native

Native only

None

On-thread

Yes (basic)

Reanimated

Web + Native

Larger

Off-thread (native), medium (web)

Yes

Motion

Web only

Medium

Off-thread (WAAPI)

Yes

You can swap drivers per platform, or dynamically load heavier drivers later in your app. For example, you can start with the lightweight CSS driver on initial load and upgrade to Motion once the user is authenticated.

Using config v6

With @tamagui/config/v6, add one animation entry for your platform. The entries share matching keys:

tamagui.config.ts

import { defaultConfig } from '@tamagui/config/v6'
import { animations } from '@tamagui/config/animations-css' // or animations-motion, animations-rn, animations-reanimated
import { createTamagui } from 'tamagui'
export const config = createTamagui({
...defaultConfig,
animations,
})

Every entry ships the same preset table, so bouncy, quick, and lazy mean the same motion whichever driver you pick. There are no 100ms-style keys: a duration is CSS now, so transition="100ms" works with nothing configured.

CSS Driver

The lightest bundle size. Springs work here too: they compile to a linear() easing that traces the real spring curve with no JavaScript running. Best for simple web-only apps.

Installation

yarn add @tamagui/animations-css

Configuration

import { createAnimations } from '@tamagui/animations-css'
import { createTamagui } from 'tamagui'
export default createTamagui({
animations: createAnimations({
fast: { duration: 160, bounce: 0.25 },
medium: { duration: 300, bounce: 0.15 },
slow: 'ease-in 450ms',
}),
// ...
})

An entry is a spring written as { duration, bounce }, or a plain CSS timing string.

Supported easing functions: ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier(x1, y1, x2, y2)

React Native Driver

Uses React Native’s built-in Animated API with no extra animation-library bundle. Use CSS, Motion, or Reanimated on web.

Installation

yarn add @tamagui/animations-react-native

Configuration

import { createAnimations } from '@tamagui/animations-react-native'
import { createTamagui } from 'tamagui'
export default createTamagui({
animations: createAnimations({
fast: { duration: 160, bounce: 0.25 },
medium: { duration: 300, bounce: 0.15 },
slow: { duration: 450, bounce: 0.1 },
}),
// ...
})

Spring parameters:

  • duration: the spring’s undamped period in milliseconds, defining how fast it feels
  • bounce: 0 is critically damped, toward 1 is loose, and negative is sluggish
  • stiffness, damping, and mass still work for a config already tuned against them

Reanimated Driver

Supports both native and web with advanced features, but has a larger bundle size. Best performance on native platforms with off-thread animations.

Installation

yarn add @tamagui/animations-reanimated react-native-reanimated

Follow the Reanimated installation guide to complete setup.

Configuration

import { createAnimations } from '@tamagui/animations-reanimated'
import { createTamagui } from 'tamagui'
export default createTamagui({
animations: createAnimations({
fast: { duration: 160, bounce: 0.25 },
medium: { duration: 300, bounce: 0.15 },
// timing animations also supported
quick: { type: 'timing', duration: 300, easing: 'ease-out' },
}),
// ...
})

Motion Driver

Off-thread performance via WAAPI with excellent spring physics and a medium bundle size. Best for web-only apps that need smooth, physics-based animations.

Installation

yarn add @tamagui/animations-motion motion

Configuration

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

Motion uses the Web Animations API (WAAPI) which runs animations on the compositor thread when possible.

Swapping Drivers

Tamagui supports several ways to use different drivers: at build time per platform, at runtime in specific parts of your app, or dynamically loaded after initial render.

Per-Platform with File Extensions

Use .native.ts and .ts file extensions to bundle different drivers per platform:

animations.ts

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

animations.native.ts

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

tamagui.config.ts

import { animations } from './animations'
export default createTamagui({
animations,
// ...
})

Dynamic with Configuration

Use the <Configuration> component to swap the animation driver for a subtree. This is useful for lazy loading heavier drivers only when needed. For example, you can keep initial page load fast with CSS animations, then upgrade to Motion for authenticated users:

app/_layout.tsx

import { Configuration, Slot } from 'tamagui'
import { createAnimations } from '@tamagui/animations-motion'
const motionDriver = createAnimations({
bouncy: { duration: 400, bounce: 0.5 },
})
export function AuthenticatedLayout() {
return (
<Configuration animationDriver={motionDriver}>
<Slot />
</Configuration>
)
}

This pattern works well with route-based code splitting, because the Motion driver is only loaded when the user navigates to an authenticated route.

Multiple Drivers with animatedBy

Configure multiple drivers at the root and select per-component:

tamagui.config.ts

import { createAnimations as createCSS } from '@tamagui/animations-css'
import { createAnimations as createSpring } from '@tamagui/animations-motion'
export default createTamagui({
animations: {
default: createCSS({ bouncy: 'ease-in 200ms' }),
spring: createSpring({ bouncy: { duration: 400, bounce: 0.5 } }),
},
})
<Square transition="bouncy" /> {/* uses default (CSS) */}
<Square animatedBy="spring" transition="bouncy" /> {/* uses spring (Motion) */}

Runtime Loading with loadAnimationDriver

Add drivers at runtime after app initialization:

import { loadAnimationDriver } from 'tamagui'
import { createAnimations } from '@tamagui/animations-motion'
// call this after some condition (user auth, route change, etc.)
const driver = createAnimations({ bouncy: { duration: 400, bounce: 0.5 } })
loadAnimationDriver('spring', driver)
// now components can use animatedBy="spring"

See also