Skip to main content

Overview

No complex animation logic required. Use your favorite classNames to trigger high-performance animations. Our translation layer ensures that your animations remain performant, responsive and 100% native.
Uniwind Pro integrates seamlessly with react-native-reanimated (v4.0.0+) to provide CSS-like animations and transitions using Tailwind classes. Instead of using the style prop with Reanimated, you can use className to animate your components. This includes CSS keyframe animations, property transitions, and Reanimated’s entering, exiting, and layout transition animations — all driven by class names.
Uniwind Pro requires Reanimated v4.0.0 or higher for animation support.

How It Works

When you use animation-related classes, Uniwind automatically:
  1. Detects animation/transition properties in your className (animate-*, transition-*, or uw-* classes)
  2. Swaps the native component for its Reanimated equivalent (e.g., ViewAnimated.View)
  3. For animate-* and transition-* classes — applies CSS animations via Reanimated’s CSS animation support
  4. For uw-entering-*, uw-exiting-*, and uw-layout-* classes — builds the corresponding Reanimated animation objects and passes them as entering, exiting, and layout props
No manual setup required - just use the classes and Uniwind handles the rest.

Keyframe Animations

Tailwind Built-in

Built-in Tailwind keyframe animations work out of the box:
import { View, Text, Pressable } from 'react-native'

// Spin animation (360° rotation loop)
<View className="size-32 bg-lime-500 rounded animate-spin" />

// Bounce animation (vertical bounce)
<View className="size-32 bg-lime-500 rounded animate-bounce" />

// Pulse animation (opacity fade in/out)
<View className="size-32 bg-lime-500 rounded animate-pulse" />

// Ping animation (scale + fade out)
<View className="size-32 bg-lime-500 rounded animate-ping" />

// Works on most components
<Pressable className="size-32 bg-base rounded-xl animate-spin" />

// iOS only (no Android support from Reanimated)
<Text className="text-default animate-spin">Spinning Text</Text>
ClassDescription
animate-spin360° rotation loop
animate-bounceVertical bounce effect
animate-pulseOpacity fade in/out
animate-pingScale up + fade out

Custom Animations

Uniwind ships additional keyframe animations beyond what Tailwind provides. These are looping animations useful for drawing attention to elements or adding visual polish:
import { View } from 'react-native'

// Gentle floating effect
<View className="size-20 bg-primary rounded-xl animate-float" />

// Heartbeat pulse
<View className="size-20 bg-red-500 rounded-full animate-heartbeat" />

// Wiggle side to side
<View className="size-20 bg-amber-500 rounded-xl animate-wiggle" />

// Elastic rubber band stretch
<View className="size-20 bg-violet-500 rounded-xl animate-rubber-band" />
ClassDescription
animate-wiggleRotational wiggle
animate-shakeHorizontal shake
animate-flashOpacity flash on/off
animate-rubber-bandElastic scale stretch
animate-swingPendulum swing
animate-tadaScale + rotate attention seeker
animate-heartbeatDouble-pulse heartbeat
animate-jelloRotational jello wobble
animate-floatGentle vertical float
animate-breatheSubtle breathing scale
animate-tiltAlternating tilt rotation
animate-glitchRapid horizontal jitter

Transitions

Animate property changes smoothly when className or state changes:
import { View, Pressable } from 'react-native'

// Transition colors on press
<Pressable
  className="size-32 bg-base rounded-xl active:bg-primary transition-colors duration-500"
/>

// Transition opacity
<View
  className={`size-32 bg-sky-800 rounded transition-opacity duration-1000 ${
    isVisible ? 'opacity-100' : 'opacity-0'
  }`}
/>

// Transition transform
<View
  className={`size-32 bg-sky-800 rounded transition-transform duration-1000 ${
    isLeft ? '-translate-x-full' : 'translate-x-full'
  }`}
/>

// Transition all properties
<View
  className={`size-32 rounded transition-all duration-1000 border-8 ${
    state
      ? '-translate-x-full bg-lime-500 border-red-500 rounded-[64px]'
      : 'translate-x-full bg-red-500 border-lime-500 rounded-none'
  }`}
/>

Transition Classes

ClassProperties Animated
transition-noneNo transition
transition-allAll properties
transition-colorsBackground, border, text colors
transition-opacityOpacity
transition-shadowBox shadow
transition-transformTransform (scale, rotate, translate)

Duration

ClassDuration
duration-7575ms
duration-100100ms
duration-150150ms
duration-200200ms
duration-300300ms
duration-500500ms
duration-700700ms
duration-10001000ms

Timing Functions

ClassEasing
ease-linearLinear
ease-inEase in
ease-outEase out
ease-in-outEase in-out

Delay

ClassDelay
delay-7575ms
delay-100100ms
delay-150150ms
delay-200200ms
delay-300300ms
delay-500500ms
delay-700700ms
delay-10001000ms

Entering & Exiting Animations

Reanimated’s entering and exiting animations let you animate components as they mount and unmount. Uniwind lets you drive these entirely through class names — no imports from react-native-reanimated needed.
No Reanimated imports required. Just add uw-entering-* and uw-exiting-* classes to your className and Uniwind builds the animation objects for you.
Use uw-entering-* to animate a component when it appears, and uw-exiting-* when it disappears:
import { useState } from 'react'
import { Button, View } from 'react-native'

const [visible, setVisible] = useState(true)

// Bounce in, bounce out
{visible && (
  <View className="size-20 bg-primary rounded-xl uw-entering-bounce-in uw-exiting-bounce-out" />
)}
<Button title={visible ? 'Hide' : 'Show'} onPress={() => setVisible(v => !v)} />

// Slide in from left, slide out to right
{visible && (
  <View className="size-20 bg-primary rounded-xl uw-entering-slide-in-left uw-exiting-slide-out-right" />
)}

// Zoom in, zoom out
{visible && (
  <View className="size-20 bg-primary rounded-xl uw-entering-zoom-in uw-exiting-zoom-out" />
)}

// Fade in slowly (1000ms)
{visible && (
  <View className="size-20 bg-primary rounded-xl uw-entering-fade-in uw-entering-duration-1000 uw-exiting-fade-out uw-exiting-duration-1000" />
)}
User-provided entering and exiting props take priority over class names. This means you can use uw-* classes as defaults and override them with props when needed.

Entering Presets

ClassAnimation
uw-entering-fade-inFade in
uw-entering-fade-in-rightFade in from the right
uw-entering-fade-in-leftFade in from the left
uw-entering-fade-in-upFade in from below
uw-entering-fade-in-downFade in from above
ClassAnimation
uw-entering-slide-in-rightSlide in from the right
uw-entering-slide-in-leftSlide in from the left
uw-entering-slide-in-upSlide in from below
uw-entering-slide-in-downSlide in from above
ClassAnimation
uw-entering-zoom-inZoom in from center
uw-entering-zoom-in-rotateZoom in with rotation
uw-entering-zoom-in-leftZoom in from the left
uw-entering-zoom-in-rightZoom in from the right
uw-entering-zoom-in-upZoom in from below
uw-entering-zoom-in-downZoom in from above
uw-entering-zoom-in-easy-upSmooth zoom in from below
uw-entering-zoom-in-easy-downSmooth zoom in from above
ClassAnimation
uw-entering-bounce-inBounce in from center
uw-entering-bounce-in-downBounce in from above
uw-entering-bounce-in-upBounce in from below
uw-entering-bounce-in-leftBounce in from the left
uw-entering-bounce-in-rightBounce in from the right
ClassAnimation
uw-entering-flip-in-x-upFlip in on X axis from top
uw-entering-flip-in-x-downFlip in on X axis from bottom
uw-entering-flip-in-y-leftFlip in on Y axis from left
uw-entering-flip-in-y-rightFlip in on Y axis from right
uw-entering-flip-in-easy-xSimple flip in on X axis
uw-entering-flip-in-easy-ySimple flip in on Y axis
ClassAnimation
uw-entering-stretch-in-xStretch in horizontally
uw-entering-stretch-in-yStretch in vertically
ClassAnimation
uw-entering-rotate-in-down-leftRotate in from bottom-left
uw-entering-rotate-in-down-rightRotate in from bottom-right
uw-entering-rotate-in-up-leftRotate in from top-left
uw-entering-rotate-in-up-rightRotate in from top-right
ClassAnimation
uw-entering-roll-in-leftRoll in from the left
uw-entering-roll-in-rightRoll in from the right
uw-entering-pinwheel-inPinwheel spin in
uw-entering-light-speed-in-rightLight speed in from right
uw-entering-light-speed-in-leftLight speed in from left

Exiting Presets

ClassAnimation
uw-exiting-fade-outFade out
uw-exiting-fade-out-rightFade out to the right
uw-exiting-fade-out-leftFade out to the left
uw-exiting-fade-out-upFade out upward
uw-exiting-fade-out-downFade out downward
ClassAnimation
uw-exiting-slide-out-rightSlide out to the right
uw-exiting-slide-out-leftSlide out to the left
uw-exiting-slide-out-upSlide out upward
uw-exiting-slide-out-downSlide out downward
ClassAnimation
uw-exiting-zoom-outZoom out to center
uw-exiting-zoom-out-rotateZoom out with rotation
uw-exiting-zoom-out-leftZoom out to the left
uw-exiting-zoom-out-rightZoom out to the right
uw-exiting-zoom-out-upZoom out upward
uw-exiting-zoom-out-downZoom out downward
uw-exiting-zoom-out-easy-upSmooth zoom out upward
uw-exiting-zoom-out-easy-downSmooth zoom out downward
ClassAnimation
uw-exiting-bounce-outBounce out from center
uw-exiting-bounce-out-downBounce out downward
uw-exiting-bounce-out-upBounce out upward
uw-exiting-bounce-out-leftBounce out to the left
uw-exiting-bounce-out-rightBounce out to the right
ClassAnimation
uw-exiting-flip-out-x-upFlip out on X axis upward
uw-exiting-flip-out-x-downFlip out on X axis downward
uw-exiting-flip-out-y-leftFlip out on Y axis to left
uw-exiting-flip-out-y-rightFlip out on Y axis to right
uw-exiting-flip-out-easy-xSimple flip out on X axis
uw-exiting-flip-out-easy-ySimple flip out on Y axis
ClassAnimation
uw-exiting-stretch-out-xStretch out horizontally
uw-exiting-stretch-out-yStretch out vertically
ClassAnimation
uw-exiting-rotate-out-down-leftRotate out to bottom-left
uw-exiting-rotate-out-down-rightRotate out to bottom-right
uw-exiting-rotate-out-up-leftRotate out to top-left
uw-exiting-rotate-out-up-rightRotate out to top-right
ClassAnimation
uw-exiting-roll-out-leftRoll out to the left
uw-exiting-roll-out-rightRoll out to the right
uw-exiting-pinwheel-outPinwheel spin out
uw-exiting-light-speed-out-rightLight speed out to right
uw-exiting-light-speed-out-leftLight speed out to left

Layout Transitions

Layout transitions animate the position and size changes of a component when its siblings are added or removed. They keep list reordering and grid changes looking smooth. Use uw-layout-* classes to apply them:
import { useState } from 'react'
import { Button, Pressable, Text, View } from 'react-native'

const [items, setItems] = useState([
  { id: 0, color: 'bg-red-400' },
  { id: 1, color: 'bg-blue-400' },
  { id: 2, color: 'bg-green-400' },
])

// Each item fades in/out and siblings animate to fill the gap
<View className="w-full gap-2">
  {items.map(item => (
    <View
      key={item.id}
      className={`w-full h-14 ${item.color} rounded-xl items-center justify-center uw-entering-fade-in uw-exiting-fade-out uw-layout-linear-transition`}
    >
      <Text className="text-white font-semibold">Item {item.id}</Text>
    </View>
  ))}
</View>
<Button title="Add item" onPress={addItem} />
You can combine layout transitions with entering and exiting animations on the same component. When an item is removed, it plays the exiting animation while its siblings smoothly reposition via the layout transition.

Layout Transition Presets

ClassDescription
uw-layout-linear-transitionSmooth linear repositioning
uw-layout-fading-transitionFade during repositioning
uw-layout-jumping-transitionBouncy jump to new position
uw-layout-curved-transitionCurved path repositioning
uw-layout-sequenced-transitionSequenced repositioning
uw-layout-entry-exit-transitionCombined entry/exit during layout

Grid Example

Layout transitions work well for grid layouts where items shift position:
import { Pressable, Text, View } from 'react-native'

<View className="w-full flex-row flex-wrap gap-2">
  {gridItems.map(item => (
    <Pressable
      key={item.id}
      className={`h-20 w-[30%] ${item.color} rounded-xl items-center justify-center uw-entering-zoom-in uw-exiting-zoom-out uw-layout-jumping-transition`}
      onPress={() => removeItem(item.id)}
    >
      <Text className="text-white font-bold text-lg">{item.id}</Text>
    </Pressable>
  ))}
</View>

Animation Configuration

You can fine-tune entering, exiting, and layout animations with modifier classes. These control duration, delay, easing, and spring physics — all from your className. The pattern is uw-{type}-{modifier} where {type} is entering, exiting, or layout.

Duration

Controls how long the animation takes. Accepts preset values or arbitrary integers.
ClassDuration
uw-{type}-duration-7575ms
uw-{type}-duration-100100ms
uw-{type}-duration-150150ms
uw-{type}-duration-200200ms
uw-{type}-duration-300300ms
uw-{type}-duration-500500ms
uw-{type}-duration-700700ms
uw-{type}-duration-10001000ms
uw-{type}-duration-{value}Arbitrary value in ms
// Slow fade in (1000ms), fast fade out (150ms)
<View className="uw-entering-fade-in uw-entering-duration-1000 uw-exiting-fade-out uw-exiting-duration-150" />

// Arbitrary duration
<View className="uw-entering-zoom-in uw-entering-duration-2000" />

Delay

Adds a delay before the animation starts.
ClassDelay
uw-{type}-delay-7575ms
uw-{type}-delay-100100ms
uw-{type}-delay-150150ms
uw-{type}-delay-200200ms
uw-{type}-delay-300300ms
uw-{type}-delay-500500ms
uw-{type}-delay-700700ms
uw-{type}-delay-10001000ms
uw-{type}-delay-{value}Arbitrary value in ms
// Fade in after 500ms delay
<View className="uw-entering-fade-in uw-entering-delay-500" />

Easing

Sets the timing function for the animation.
ClassEasing
uw-{type}-ease-linearLinear
uw-{type}-ease-inEase in (accelerating)
uw-{type}-ease-outEase out (decelerating)
uw-{type}-ease-in-outEase in-out (both)
uw-{type}-ease-bounceBounce easing
// Bounce in with bounce easing
<View className="uw-entering-bounce-in uw-entering-ease-bounce uw-exiting-bounce-out" />

Spring Physics

For spring-based animations, enable springify and optionally configure damping, stiffness, and mass. These accept arbitrary numeric values.
ClassDescription
uw-{type}-springifyEnable spring physics
uw-{type}-damping-{value}Spring damping (lower = more oscillation)
uw-{type}-stiffness-{value}Spring stiffness (higher = snappier)
uw-{type}-mass-{value}Spring mass (higher = slower)
// Spring-based zoom in with low damping for a bouncy effect
<View className="uw-entering-zoom-in uw-entering-springify uw-entering-damping-10 uw-exiting-zoom-out" />

// Stiff spring with high stiffness
<View className="uw-entering-slide-in-left uw-entering-springify uw-entering-stiffness-200 uw-entering-damping-15" />
Replace {type} with entering, exiting, or layout depending on which animation phase you want to configure. Each phase is configured independently, so you can have a slow entering animation and a fast exiting animation on the same component.

Using Reanimated Directly

If you need more control than class names provide, you can use Reanimated’s Animated.* components directly with Uniwind classes. The entering, exiting, and layout props accept Reanimated animation objects as usual:
import Animated, { FadeIn, FlipInXUp, LinearTransition } from 'react-native-reanimated'

// Entering/exiting animations
<Animated.Text
  entering={FadeIn.delay(500)}
  className="text-foreground text-lg"
>
  Fading in text
</Animated.Text>

// Animated FlatList with entering animations per item
<Animated.FlatList
  data={data}
  className="flex-none"
  contentContainerClassName="px-2"
  layout={LinearTransition}
  ItemSeparatorComponent={() => (
    <Animated.View className="h-px bg-border" />
  )}
  renderItem={({ item }) => (
    <Animated.Text
      entering={FlipInXUp}
      className="text-foreground py-2"
    >
      {item}
    </Animated.Text>
  )}
/>
You can also mix both approaches. Pass an entering or exiting prop directly to override the class-name-driven animation:
import { FadeIn } from 'react-native-reanimated'
import { View } from 'react-native'

// uw-entering-bounce-in is overridden by the entering prop
<View
  entering={FadeIn.duration(800)}
  className="size-20 bg-primary rounded-xl uw-entering-bounce-in uw-exiting-bounce-out"
/>

Components Supporting Animations

These components automatically switch to Reanimated versions when animate-*, transition-*, or uw-* animation classes are detected:
ComponentAnimated Version
ViewAnimated.View
TextAnimated.Text
ImageAnimated.Image
ImageBackgroundAnimated.ImageBackground
ScrollViewAnimated.ScrollView
FlatListAnimated.FlatList
TextInputAnimated.TextInput
PressableAnimated.Pressable
All of these components accept entering, exiting, and layout props when animation classes are present. You can also pass these props directly without any uw-* classes — the component will be upgraded to its Reanimated version automatically.

Practical Examples

Animated Button

import { Pressable, Text } from 'react-native'

<Pressable
  className="px-6 py-3 bg-blue-500 rounded-lg active:scale-95 active:bg-blue-600 transition-all duration-150"
>
  <Text className="text-white font-semibold">Press Me</Text>
</Pressable>

Interactive Card

import { Pressable, Text } from 'react-native'

<Pressable
  className="p-4 bg-white rounded-xl active:scale-95 transition-transform duration-150"
>
  <Text className="text-gray-800">Interactive Card</Text>
</Pressable>

Disabled State with Transition

import { Pressable, Text } from 'react-native'

<Pressable
  disabled={isLoading}
  className="px-6 py-3 bg-blue-500 disabled:bg-gray-300 rounded-lg transition-colors duration-300"
>
  <Text className="text-white">Submit</Text>
</Pressable>

Loading Spinner

import { View } from 'react-native'

<View className="size-8 border-4 border-gray-200 border-t-blue-500 rounded-full animate-spin" />

Animated List with Reordering

import { useState } from 'react'
import { Button, Text, View } from 'react-native'

const COLORS = ['bg-red-400', 'bg-blue-400', 'bg-green-400', 'bg-yellow-400', 'bg-purple-400']
let nextId = 0

export default function AnimatedList() {
  const [items, setItems] = useState([
    { id: nextId++, color: COLORS[0] },
    { id: nextId++, color: COLORS[1] },
    { id: nextId++, color: COLORS[2] },
  ])

  const addItem = () => {
    const color = COLORS[nextId % COLORS.length]
    setItems(prev => [...prev, { id: nextId++, color }])
  }

  const removeItem = (id: number) => {
    setItems(prev => prev.filter(item => item.id !== id))
  }

  return (
    <View className="flex-1 p-4 gap-2">
      {items.map(item => (
        <View
          key={item.id}
          className={`w-full h-14 ${item.color} rounded-xl flex-row items-center px-4 justify-between uw-entering-fade-in uw-exiting-fade-out uw-layout-linear-transition`}
        >
          <Text className="text-white font-semibold">Item {item.id}</Text>
          <Button title="Remove" onPress={() => removeItem(item.id)} />
        </View>
      ))}
      <Button title="Add item" onPress={addItem} />
    </View>
  )
}

Shadow Tree Updates

Learn how Uniwind Pro updates views without re-renders

Theme Transitions

Add smooth animated transitions when switching themes