React Native Reanimated 4 v roce 2026: Kompletní průvodce animacemi, migrací a 120 FPS výkonem

Praktický průvodce React Native Reanimated 4 v roce 2026: nové CSS API, migrace z verze 3, gestura, multi-runtime, optimalizace 120 FPS a řešení častých chyb jako duplicate worklet instances.

Reanimated 4 React Native 2026: 120 FPS animace

Upřímně, Reanimated 4 byl pro mě jedním z nejvýraznějších přelomů, co jsem v React Native ekosystému za posledních pár let zažil. V roce 2025 vyšel a v roce 2026 už je to prostě defaultní volba pro plynulé 120 FPS animace nad Fabric architekturou. Pokud spravujete app postavenou na trojce nebo přemýšlíte, jak se vyhnout té otravné chybě „duplicate worklet instances" a propadům FPS u dlouhých seznamů, tenhle průvodce vás provede krok za krokem – od instalace až po pokročilou optimalizaci.

Co je nového v Reanimated 4

Reanimated 4 není jen verze s lepším výkonem. Je to spíš architektonický restart knihovny. Tady jsou hlavní změny, na které si dejte pozor:

  • Vyžaduje New Architecture (Fabric + TurboModules). Stará architektura už není podporována, což zjednodušuje interní kód, ale vynucuje migraci – ať chcete, nebo ne.
  • Worklety se odstěhovaly do samostatného balíčku react-native-worklets. Babel plugin teď žije tam, ne v Reanimated (a tohle je mimochodem zdroj asi 80 % chyb při migraci).
  • Nové deklarativní CSS-kompatibilní API – animace a tranzice se dají psát stylem známým z webu (transition, animation property ve StyleSheet).
  • Nové runtime API: runOnRuntimeSync, runOnRuntimeAsync, scheduleOnRuntimeWithId pro multi-runtime scénáře (worker thread, audio thread).
  • Shareable typ s C++ bindings – stabilní sdílená paměť mezi JS a UI runtime.
  • Energy-based physics – spring animace se ukončují podle skutečné energie systému, ne podle nějakého libovolného epsilonu. Konečně.

Pokud jste minuli související přechod Reactu, mrkněte se nejdřív na Novou architekturu React Native v roce 2026 – Reanimated 4 na ní staví přímo.

Předpoklady a kompatibilita

K květnu 2026 platí tohle:

  • React Native 0.78+ (poslední tři minor verze)
  • Expo SDK 53+
  • Zapnutá New Architecture (newArchEnabled=true v app.json / Gradle / Podfile)
  • Node 20+, Hermes engine
  • Xcode 16, Android Gradle Plugin 8.5+

Kompatibilní matice

Reanimated 4.2.x  ↔  RN 0.78–0.80  ↔  Worklets 0.6.x  ↔  Expo SDK 53+
Reanimated 4.1.x  ↔  RN 0.76–0.78  ↔  Worklets 0.5.x  ↔  Expo SDK 52
Reanimated 3.16.x ↔  RN 0.74–0.76  (poslední 3.x – LTS do konce 2026)

Instalace v novém projektu (Expo)

Začneme tím jednodušším scénářem – nový projekt na zelené louce:

npx create-expo-app@latest moje-aplikace --template default
cd moje-aplikace
npx expo install react-native-reanimated react-native-worklets

Otevřete babel.config.js a přidejte plugin z balíčku worklets (ne z Reanimated – tohle bývala asi nejčastější chyba při migraci):

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['react-native-worklets/plugin'],
  };
};

Plugin musí být poslední v seznamu. Tečka. V metro.config.js pak nepotřebujete nic dalšího – Reanimated 4 si Metro detekuje automaticky.

Migrace z Reanimated 3 na 4

Migrace je v drtivé většině případů API-kompatibilní, ale je tu pár bodů, které vás zaručeně chytí. Tady jsou:

1. Přesun Babel pluginu

V babel.config.js jednoduše nahraďte:

// PŘEDTÍM (Reanimated 3)
plugins: ['react-native-reanimated/plugin']

// NYNÍ (Reanimated 4)
plugins: ['react-native-worklets/plugin']

Zapomenutí na tuhle změnu se projeví jako runtime error ReanimatedError: Tried to synchronously call a non-worklet function on the UI thread. Mně osobně to zabralo asi hodinu googlení, než mi došlo, co je špatně. Ušetřete si to.

2. Zapnutí New Architecture

V app.json (Expo) nebo android/gradle.properties + ios/Podfile musíte explicitně povolit:

{
  "expo": {
    "newArchEnabled": true
  }
}

Bez tohohle Reanimated 4 neproběhne ani build – Pod install hlásí Reanimated 4 requires New Architecture.

3. Vyčištění caches po upgrade

Tohle vypadá brutálně, ale věřte mi – ušetří vás to hodin debugu:

rm -rf node_modules ios/Pods ios/build android/build android/app/build
watchman watch-del-all
npm install
cd ios && pod install && cd ..
npx expo start --clear

4. Drobné API přejmenování

  • useAnimatedGestureHandler je oficiálně deprecated – přejděte na react-native-gesture-handler v3+ a Gesture.Pan() API.
  • useDerivedValue teď vyžaduje, aby vrátil hodnotu synchronně; asynchronní derivace selže s warningem.

Základní animace: shared values a animované styly

Pokud jste s Reanimated zatím nepracovali, jádro stojí na třech konceptech:

  1. useSharedValue – stav, který žije na UI threadu a JS o něm ví.
  2. useAnimatedStyle – worklet, který z shared values počítá style props.
  3. withSpring / withTiming / withDecay – wrappery, které ze surových hodnot dělají časované přechody.

Klasický příklad – tlačítko, které pulsuje při stisku:

import { Pressable, StyleSheet, Text } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

export function PulseButton() {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));

  return (
    <Pressable
      onPressIn={() => (scale.value = withSpring(0.92))}
      onPressOut={() => (scale.value = withSpring(1))}
    >
      <Animated.View style={[styles.button, animatedStyle]}>
        <Text style={styles.label}>Stisknout</Text>
      </Animated.View>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  button: { padding: 16, backgroundColor: '#4f46e5', borderRadius: 12 },
  label: { color: 'white', fontWeight: '600', textAlign: 'center' },
});

Nové CSS-kompatibilní API: kdy ho použít

Reanimated 4 přinesl deklarativní stylovou variantu, která vypadá takřka stejně jako CSS na webu. Hodí se pro jednoduché tranzice a stavem řízené animace, kde nepotřebujete gestura ani fyziku.

import Animated from 'react-native-reanimated';
import { useState } from 'react';
import { Pressable, StyleSheet } from 'react-native';

export function ExpandingCard() {
  const [open, setOpen] = useState(false);

  return (
    <Pressable onPress={() => setOpen((p) => !p)}>
      <Animated.View
        style={[
          styles.card,
          {
            height: open ? 220 : 80,
            backgroundColor: open ? '#0ea5e9' : '#1e293b',
            transitionProperty: ['height', 'backgroundColor'],
            transitionDuration: '300ms',
            transitionTimingFunction: 'ease-out',
          },
        ]}
      />
    </Pressable>
  );
}

const styles = StyleSheet.create({
  card: { borderRadius: 16, marginHorizontal: 16 },
});

CSS API vs. worklet API

KritériumCSS APIWorklet API
Závisí na gestuNeAno
Reakce na props/stavVynikajícíVyžaduje víc boilerplate
Fyzika (spring, decay)OmezenáPlná
Bundle velikostMenšíStejná
VýkonStejný – obojí běží na UI threaduStejný

Pravidlo palce (které mi za poslední rok ušetřilo spoustu nervů): pokud animaci spouští stav komponenty (boolean, číslo z propsy), pište CSS API. Pokud ji řídí gesture nebo scroll position, držte se worklet API.

Gestura s Gesture Handler v3

Drag-to-dismiss bottom sheet s pružinovým návratem – kanonický příklad propojení gestur a Reanimated:

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

export function Draggable() {
  const translateY = useSharedValue(0);

  const pan = Gesture.Pan()
    .onChange((e) => {
      translateY.value += e.changeY;
    })
    .onEnd((e) => {
      if (Math.abs(e.velocityY) > 800) {
        translateY.value = withSpring(e.velocityY > 0 ? 600 : -600, {
          velocity: e.velocityY,
        });
      } else {
        translateY.value = withSpring(0);
      }
    });

  const style = useAnimatedStyle(() => ({
    transform: [{ translateY: translateY.value }],
  }));

  return (
    <GestureDetector gesture={pan}>
      <Animated.View style={[{ width: 240, height: 240, backgroundColor: '#10b981', borderRadius: 24 }, style]} />
    </GestureDetector>
  );
}

Layout animace a entering/exiting tranzice

Reanimated 4 zachovává prediktivní layout API. Pro připnutí/odebrání položek ze seznamu stačí pár řádek:

import Animated, { FadeIn, FadeOut, Layout } from 'react-native-reanimated';

<Animated.View
  entering={FadeIn.duration(220)}
  exiting={FadeOut.duration(160)}
  layout={Layout.springify().damping(14)}
/>

V Reanimated 4 byly tyhle presety přepsány tak, aby běžely čistě v Fabric C++ vrstvě. Díky tomu jsou znatelně levnější u dlouhých seznamů – a u FlashListu s 5000+ položkami to opravdu poznáte.

Optimalizace výkonu: 120 FPS bez kompromisů

Reanimated 4 cílí na 120 FPS displeje (ProMotion, většina Androidu high-end). Ale to neznamená, že je dostanete zdarma. Tady jsou nejčastější brzdy, na které jsem v praxi narazil:

1. Propady FPS u FlatList / FlashList

Pokud při scrollu animujete položky individuálně (například shimmer placeholder), zapněte independent scroll a zabalte styly:

<FlashList
  data={items}
  renderItem={renderRow}
  removeClippedSubviews
  drawDistance={250}
  estimatedItemSize={72}
/>

A v renderRow používejte useAnimatedStyle jen pro transform a opacity. Animace width, height nebo backgroundColor vynutí relayout – a 120 FPS zapomeňte.

2. Vyhněte se runOnJS v hot pathu

Každé volání runOnJS přepíná thread. V onChange gestur ho fakt nepoužívejte – přesuňte logiku do worklet vrstvy a JS volejte až v onEnd.

3. Měřte přes nový Reanimated Profiler

import { startProfiling, stopProfiling } from 'react-native-reanimated';

startProfiling();
// ...interakce...
const report = await stopProfiling();
console.log(report.uiThreadFps, report.jsThreadFps);

Multi-runtime: práce s worker threadem

Nové runtime API umožňuje rozjet těžkou výpočetní práci mimo UI a JS thread. Tohle byla pro mě jedna z hlavních věcí, na které jsem se z Reanimated 4 těšil:

import { createWorkletRuntime, runOnRuntimeAsync } from 'react-native-worklets';

const heavyRuntime = createWorkletRuntime('image-processor');

async function processImage(buffer) {
  return await runOnRuntimeAsync(heavyRuntime, (data) => {
    'worklet';
    // CPU-náročná transformace
    return transform(data);
  })(buffer);
}

Použitelné pro real-time obraz, audio buffery nebo parsování velkých JSONů bez blokování UI.

Časté chyby a jejich řešení

„Duplicate worklet instances"

Vzniká, když máte v projektu jak react-native-reanimated/plugin, tak react-native-worklets/plugin. Smažte ten starý a vyčistěte cache:

npx expo start --clear

„Reanimated 4 requires New Architecture"

Zkontrolujte app.json, android/gradle.properties (newArchEnabled=true) a ios/Podfile (:fabric_enabled => true).

Animace nereaguje, žádná chyba

Téměř vždy chybí Babel plugin nebo není poslední v poli pluginů. A ověřte, že animovaný komponent je <Animated.View>, ne obyčejný <View> – to je klasika, na kterou každý jednou narazí.

Srovnání s Moti, Framer Motion a Skia

KnihovnaHodí se naZávisí na Reanimated?
Reanimated 4Univerzální nízko-úrovňový základ
MotiDeklarativní zápis tranzic, prototypyAno (wrap nad Reanimated)
React Native SkiaVlastní vykreslování, canvas, shaderyDoplňuje (ne nahrazuje)
LottieAfter Effects exporty, ikonové animaceNe

V roce 2026 je běžný stack tenhle: Reanimated 4 + Gesture Handler v3 pro interakce, Skia pro vlastní vykreslování a Lottie pro statické vektorové animace z designerského pipeline. Funguje to dobře a moc bych si nevymýšlel.

FAQ

Jak migrovat z Reanimated 3 na Reanimated 4?

Zapněte New Architecture, nainstalujte react-native-worklets, v babel.config.js nahraďte react-native-reanimated/plugin za react-native-worklets/plugin a vyčistěte všechny cache (node_modules, Pods, Gradle build, Metro). API komponent zůstává v 95 % případů identické.

Funguje Reanimated 4 na staré architektuře React Native?

Ne. Reanimated 4 vyžaduje Fabric a TurboModules. Pokud aplikaci ještě nemůžete migrovat, zůstaňte na Reanimated 3.16 LTS – bude podporován minimálně do konce roku 2026.

Kdy použít CSS API a kdy klasické worklety?

CSS API zvolte u animací řízených stavem komponenty (boolean, prop). Worklet API použijte u všeho, co reaguje na gesto, scroll position nebo potřebuje fyziku (spring, decay).

Je react-native-worklets povinná závislost?

Ano. Reanimated 4 worklety neobsahuje – jsou v samostatném balíčku, který obsluhuje Babel plugin i runtime infrastrukturu. Bez něj projekt nesestaví.

Proč při scrollování FlatListu padají FPS u animovaných řádků?

Nejčastější příčinou je animace layout-vlastností (width, height, margin), která spouští relayout celého seznamu. Držte se animací transform a opacity, používejte FlashList s pevným estimatedItemSize a vyhněte se runOnJS v každém framu.

Závěr

Reanimated 4 představuje technologický skok, který platí daň v podobě povinné migrace na New Architecture. Ale výměnou nabízí stabilní 120 FPS, multi-runtime možnosti a deklarativní CSS API – a to za to podle mě stojí. Pokud začínáte nový projekt v roce 2026, jděte rovnou do Reanimated 4. Pokud spravujete legacy 3.x kód, plánujte migraci v rámci širšího přechodu na Fabric – obě změny můžete udělat současně a ušetřit si dva oddělené retesty.

O Autorovi Editorial Team

Our team of expert writers and editors.