React Native Reanimated is one of the most powerful libraries for creating smooth, performant animations in React Native. With the release of Reanimated 4, the library has become even more intuitive and efficient, making it easier than ever to build complex animations. Pairing it with NativeWind, a utility-first CSS framework for React Native, can supercharge your development workflow by combining declarative animations with a clean, Tailwind-like styling approach.
In this guide, we’ll walk through the basics of React Native Reanimated 4 and how to integrate it with NativeWind to create a seamless development experience. Let’s dive in!
What is React Native Reanimated?
React Native Reanimated is a library that allows you to create smooth, high-performance animations by running them on the native thread instead of the JavaScript thread. This avoids the performance bottlenecks often associated with JavaScript-driven animations, especially on lower-end devices.
With Reanimated 4, the API has been simplified, and new features like shared element transitions and improved gesture handling have been added, making it a must-have tool for any React Native developer.
What is NativeWind?
NativeWind is a library that brings the utility-first styling of Tailwind CSS to React Native. It allows you to write styles directly in your components using Tailwind-like class names, making your code more readable and maintainable. By combining NativeWind with Reanimated, you can create beautifully animated UIs with minimal effort.
Setting Up Your Project
Before we start, make sure you have a React Native project set up. If you don’t, you can create one using:
npx create-expo-app@latest AnimatedApp
Next, install the required dependencies:
npm install react-native-reanimated react-native-gesture-handler nativewind
For NativeWind to work, you’ll also need to install tailwindcss and configure it. Run:
npm install tailwindcss
npx tailwindcss init
Then, create a tailwind.config.js file and configure it to include your project files:
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
Finally, create a global.css file in your project and add the following:
@tailwind base;
@tailwind components;
@tailwind utilities;
Import this file in your App.js:
import './global.css';
Using Reanimated with NativeWind
Now that your project is set up, let’s create a simple animated component using Reanimated and style it with NativeWind.
Step 1: Create a Basic Animation
Let’s start by creating a simple fade-in animation using Reanimated.
import React from 'react';
import { View, Text, Button } from 'react-native';
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
const App = () => {
const opacity = useSharedValue(0);
const fadeIn = () => {
opacity.value = withTiming(1, { duration: 1000 });
};
const animatedStyle = useAnimatedStyle(() => {
return {
opacity: opacity.value,
};
});
return (
<View className="flex-1 justify-center items-center bg-white">
<Animated.View style={animatedStyle} className="p-4 bg-blue-500 rounded-lg">
<Text className="text-white">Hello, Reanimated 4!</Text>
</Animated.View>
<Button title="Fade In" onPress={fadeIn} className="mt-4" />
</View>
);
};
export default App;
Explanation:
- useSharedValue: This hook creates a shared value that can be animated. Here, we use it to control the opacity of the Animated.View.
- useAnimatedStyle: This hook creates a style object that updates whenever the shared value changes.
- withTiming: This function animates the shared value over a specified duration.
Step 2: Style with NativeWind
Notice how we’ve used NativeWind’s utility classes like flex-1, justify-center, items-center, bg-white, p-4, bg-blue-500, and rounded-lg to style our components. This makes the code more readable and eliminates the need for separate stylesheets.
Advanced Example: Animated Button with NativeWind
Let’s create a more advanced example: a button that scales when pressed.
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
const App = () => {
const scale = useSharedValue(1);
const onPressIn = () => {
scale.value = withSpring(0.9);
};
const onPressOut = () => {
scale.value = withSpring(1);
};
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ scale: scale.value }],
};
});
return (
<View className="flex-1 justify-center items-center bg-white">
<TouchableOpacity onPressIn={onPressIn} onPressOut={onPressOut}>
<Animated.View style={animatedStyle} className="p-4 bg-purple-500 rounded-lg shadow-lg">
<Text className="text-white font-bold">Press Me</Text>
</Animated.View>
</TouchableOpacity>
</View>
);
};
export default App;
Explanation:
- withSpring: This function creates a spring-based animation, which gives the button a bouncy effect.
- onPressIn and onPressOut: These handlers trigger the animation when the button is pressed and released.
Why Use Reanimated with NativeWind?
- Performance: Reanimated ensures your animations run smoothly on the native thread.
- Developer Experience: NativeWind’s utility-first approach makes styling faster and more intuitive.
- Readability: Combining the two libraries keeps your code clean and easy to understand.
Conclusion
React Native Reanimated 4 and NativeWind are a match made in heaven for building performant, beautifully animated UIs. With Reanimated’s powerful animation capabilities and NativeWind’s utility-first styling, you can create stunning apps with minimal effort.
Give it a try in your next project, and let us know how it goes! Happy coding! 🚀