How to make an animated heart like button in React Native
By the LumioUI team · Updated
An animated like button is a heart that fills when tapped, gives a small pulse and a haptic tick, and updates the like count in place. In React Native, keep liked in state, animate the fill and scale with Reanimated, and update the server optimistically so it feels instant. The LumioUI Like Button fills from the bottom up with a soft glow, and fills the same way when someone double-taps a photo.
Live demo of the LumioUI Like Button component. It's interactive, so try it.
How the heart animation works
- Two layers. An outline heart with a filled heart on top. Animate the fill's opacity, or for a nicer effect a clip that reveals it from the bottom up.
- A short pulse on like only. Press in slightly, then spring back. Don't pulse on unlike, which should stay quiet.
- Haptics. A light selection tick confirms the tap without a sound.
- Optimistic count. Change the number before the request returns, and roll back if it fails. Animate only the digits that change.
- Double-tap to like. A double tap on the photo should set the same state and play the same fill, never toggle it off.
- Accessibility. A 44pt touch target (use
hitSlop),accessibilityState.selected, and a label that names the action.
import * as React from "react";
import { Pressable, Text } from "react-native";
import * as Haptics from "expo-haptics";
import Animated, { useAnimatedStyle, useSharedValue, withSequence, withSpring, withTiming } from "react-native-reanimated";
export function Heart({ liked, onChange, count }) {
const scale = useSharedValue(1);
const fill = useSharedValue(liked ? 1 : 0);
const press = () => {
const next = !liked;
onChange(next);
Haptics.selectionAsync();
fill.value = withTiming(next ? 1 : 0, { duration: 220 });
if (next) scale.value = withSequence(withTiming(0.85, { duration: 80 }), withSpring(1, { damping: 8, stiffness: 300 }));
};
const heart = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] }));
const inner = useAnimatedStyle(() => ({ opacity: fill.value }));
return (
<Pressable onPress={press} hitSlop={10}
accessibilityRole="button" accessibilityLabel="Like" accessibilityState={{ selected: liked }}>
<Animated.View style={heart}>
<Text>♡</Text>
<Animated.Text style={[{ position: "absolute", color: "#ff3b5c" }, inner]}>♥</Animated.Text>
</Animated.View>
<Text>{count}</Text>
</Pressable>
);
} The quick way: LumioUI Like Button
The Like Button fills from the bottom up with a soft glow, updates the count in place, ticks a haptic and respects reduced motion. It's free and runs in Expo Go.
import * as React from "react";
import { LikeButton } from "@/components/ui/like-button/like-button";
// post.likes is your store's count; update it with the same optimistic change.
export function PostActions({ post }) {
const [liked, setLiked] = React.useState(post.likedByMe);
return (
<LikeButton
liked={liked}
onLikedChange={(next) => {
setLiked(next);
api.setLiked(post.id, next); // optimistic: the UI already changed
}}
count={post.likes}
variant="plain"
size="md"
/>
);
} likedandonLikedChangemake it controlled. UsedefaultLikedto let it manage itself.countwithformatCountshortens big numbers (1.2K).hideCounthides the number.variantis"plain","pill"or"overlay"(for photos), andsizeis"sm","md"or"lg".noBurstandhaptictune the feedback.- For bookmarks use Save Button. For emoji reactions use Reaction Picker (Pro).
Add it to your app
LumioUI's CLI copies the component's source into your project, so it's yours to read and change. Run init once per project:
npx @lumioui/cli init
npx @lumioui/cli add like-button It works in Expo (SDK 54+) and bare React Native, with Reanimated 4 and NativeWind. See the installation guide and the full Like Button API.
Related components
- Save Button (Pro)
- Follow Button (Pro)
- Reaction Picker (Pro)
- Post Card (Pro)
More React Native guides
- How to make a bottom sheet in React Native
- Animated tabs with a sliding indicator in React Native
- How to show toast notifications in React Native
- Skeleton loading screens in React Native
- How to add dark mode and a theme toggle in React Native
- How to build an accordion in React Native
- How to make a side drawer menu in React Native
- How to make a modal dialog in React Native
- How to build an animated carousel in React Native
- How to make an animated splash screen in React Native and Expo
- How to build a month calendar in React Native