開発

React Native Reanimatedとは?UIスレッド駆動の仕組みと4系の版の縛り【2026年8月時点】

react-native-reanimatedは、React Nativeのアニメーションを毎フレームUIスレッド側で計算させるためのライブラリです。JavaScript側が重い処理で詰まっていても指の動きに画面が追従する、という性質がこのライブラリの中身にあたります。2026年8月19日時点の安定版は4.5.3で、3系との一番の違いはworklet(UIスレッドで動く小さな関数)の実装がreact-native-workletsという別パッケージへ切り出されたことです。この記事では、動作の仕組み、4系で変わった構成と版の組み合わせ条件、フックAPIとCSS記法の書き分け、Gesture Handlerとの連携、そして受託案件での採用可否を実装目線で整理します。React Native自体の構造はReact Nativeとは?仕組みとNew Architectureの構造・採用判断を実装目線で解説にまとめてあります。

まとめ:4系はworklets分離が前提、詰まるのは版の組み合わせ

先に結論を示します。Reanimatedを入れる目的は、アニメーションの計算をJavaScriptスレッドから引き剥がすことにあります。値の入れ物である共有値と、UIスレッドで走るworkletの2つを覚えれば、書き方そのものは難しくありません。

実務でつまずくのは記法ではなく版の組み合わせです。2026年8月19日時点の公式互換表では、Reanimated 4.5.xの対応はReact Native 0.83〜0.86までとなっており、2026年8月11日に出たReact Native 0.87.0はまだこの範囲の外にあります。加えて4系はNew Architecture専用で、旧アーキテクチャのままのアプリは3系(3.19.5・2025年12月22日公開で更新が止まっている)に留まる形になります。

Expoを使う場合はさらに固定されます。Expo SDK 57のバンドル定義はReact Native 0.86.2・Reanimated 4.5.1・worklets 0.10.1・Gesture Handler 2.32.0で、Gesture Handlerは3系が2026年5月28日に出た後もなお2系のままです。個別に上げる前に、この定義を先に見るのが安全な進め方になります。

ReanimatedがUIスレッドで動く仕組みとAnimatedとの差

React Native標準のAnimated APIでもuseNativeDriverを有効にすればネイティブ側でアニメーションが進みます。ただし対象はtransformopacityなどに限られ、途中でJavaScript側の判断を挟む動きは扱えません。Reanimatedはこの制約の外側を埋める設計です。

workletの宣言とUIランタイムが担う毎フレーム更新の流れ

公式の用語集にあるworkletの定義は「Worklets are short-running JavaScript functions that can be run on the UI thread」です。関数の先頭に'worklet'と書くか、Reanimatedのフックへ渡すことで、その関数はJavaScriptランタイムではなくUIランタイムで実行されます。UIランタイムは描画スレッド上に用意された別のJavaScript実行環境で、ここで走る限りJavaScript側の混雑とは無関係にフレームが進みます。

4系ではこの仕組みがreact-native-workletsへ分離されました。Reanimatedはその利用者の1つという位置づけに変わり、Babelプラグインの指定先もworklets側へ移っています。週間ダウンロード数を見ると、2026年8月9日から15日でReanimatedが約635万、workletsが約562万と近い水準にあり、分離後の依存関係がそのまま数字に出ています。

共有値がJSスレッドとUIスレッドをまたいで同期する仕組みの整理

もう1つの柱が共有値です。useSharedValueで作った入れ物は.valueで読み書きでき、両方のスレッドから同じ実体を触れます。ここへwithTimingwithSpringの戻り値を代入すると、UIスレッド側が毎フレームの値を算出してスタイルへ流し込みます。Reactの状態と違って再レンダリングを起こさないため、指の移動のような高頻度の更新でもコンポーネントツリーは静止したままです。

JavaScript側の関数を呼び戻したいときはscheduleOnRNを使います。3系のrunOnJSにあたるもので、4系では改称のうえworkletsパッケージ側へ移りました。逆方向のrunOnUIscheduleOnUIです。この往復を挟むとフレームの外へ処理が出るため、アニメーションの完了通知や画面遷移の起動といった1回きりの用途に絞るのが定石になります。

Reanimated 4系で変わった構成とバージョンの組み合わせ条件

4系は積み重ねを一度整理した版で、依存関係と対応表の両方が変わりました。導入時に確認すべき事実を先に押さえておきます。

react-native-workletsの分離で何が変わったのか

移行ガイドが求める作業は3つです。第1にreact-native-workletsを追加インストールしてネイティブを再ビルドすること。第2にbabel.config.jsのプラグイン指定を差し替えること。第3にworklet関連の関数をworkletsパッケージからのimportへ書き換えることです。旧名はReanimated側から再エクスポートされていますが非推奨扱いで、将来の版で消える予定と明記されています。

// babel.config.js(4系)
module.exports = {
  presets: ['babel-preset-expo'],
  plugins: ['react-native-worklets/plugin'],  // 3系は react-native-reanimated/plugin
};

APIの改称もまとめて入りました。runOnJSscheduleOnRNrunOnUIscheduleOnUIrunOnRuntimescheduleOnRuntimemakeShareableCloneRecursivecreateSerializableへ変わります。useWorkletCallbackは廃止で、useCallbackの中に'worklet'を書く形へ置き換えます。useScrollViewOffsetuseScrollOffsetへ改称されました。挙動面ではwithSpringの停止判定がenergyThreshold1つに集約され、durationは知覚上の長さを表す値になって実時間はおよそ1.5倍になります。既存の値をそのまま持ち込むと体感速度がずれるため、移行時は見た目で詰め直してください。

対応表で確かめる React Native と Expo SDK の版の縛り

公式の互換表は、Reanimatedの版ごとに対応するReact Nativeの範囲を明示しています。2026年8月19日時点の主要な行は次のとおりです。

Reanimated React Native worklets
4.5.x(安定版) 0.83〜0.86 0.10〜0.11.x
4.3.x 0.81〜0.86 0.8.x
4.1.x 0.78〜0.82 0.5〜0.8.x
4.0.x 0.78〜0.81 0.4.x
3.19.5(旧系) 旧アーキ向け 導入不可

ここで注意したいのが上端です。React Native 0.87.0の公開日は2026年8月11日ですが、安定版Reanimatedの対応表は0.86までで止まっています。素のReact Nativeで最新版へ追随している現場では、Reanimated側の対応が入るまで待つか、動作確認を自前で持つかの判断が必要です。Expo環境なら判断は単純で、SDK 57のバンドル定義が示す組み合わせ(React Native 0.86.2・Reanimated 4.5.1・worklets 0.10.1)に揃えれば済みます。Expo側の版管理の考え方はExpo(React Native)とは?Expo Go・開発ビルド・EASの役割と採用判断で整理しています。

なお表の最下段について補足すると、3系とreact-native-workletsは共存できません。公式互換表にも「Reanimated 3 will not work with react-native-worklets installed」と書かれています。移行の途中で両系統を同居させる逃げ道はない、と読んでおくのが安全です。

アニメーションの書き方:フックAPIと4系のCSS記法の使い分け

4系には書き方が2通りあります。従来からのフックAPIと、4系で入ったCSS風の記法です。どちらが上位ということはなく、動きの決まり方で選び分けます。

useSharedValueとuseAnimatedStyleで作る基本の流れ

フックAPIは共有値を自分で持ち、スタイルを組み立てるworkletを書く形です。値の出どころを自分で決められるため、指の位置やスクロール量に連動させる動きはこちらになります。

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

const offset = useSharedValue(0);
const style = useAnimatedStyle(() => ({
  transform: [{ translateX: offset.value }],
}));

// 値を代入した時点でUIスレッド側が毎フレーム計算する
offset.value = withSpring(120);

useAnimatedStyleへ渡した関数はworkletとして扱われ、参照している共有値が変わるたびUIスレッドで再評価されます。適用先はAnimated.ViewのようにReanimatedが用意したコンポーネントに限られる点だけ気をつけてください。

Reanimated 4系で入ったCSS記法が向く場面と向かない場面

もう一方の記法は、キーフレームをオブジェクトで書いてスタイルにanimationNameとして渡すやり方です。開始状態は現在のスタイルが使われ、キーフレームは最低1つあれば動きます。同じプロパティを狙う指定が複数あるときは後に書いたものが優先です。Android・iOS・Webのいずれでも同じように扱えます。

向くのは、入場や強調のように始点と終点が決まっている動きです。共有値もフックも要らず、スタイルへ書くだけで済みます。向かないのは、途中の値を外から動かしたい動きです。ドラッグ追従やスクロール連動のように毎フレームの入力がある場合は、フックAPIのほうが素直に書けます。1つの画面で両方を混ぜても差し支えありませんが、同じプロパティを両方から触ると後勝ちの規則に巻き込まれるため、対象プロパティは分けておくのが無難です。

Gesture Handler連携とv3で変わった書き方の対応

指の操作に追従する動きを作るなら、react-native-gesture-handlerとの併用が前提になります。Reanimated単体では入力イベントを受け取れないためです。

useAnimatedGestureHandler廃止後の新しい書き方の要点

4系でuseAnimatedGestureHandlerは廃止されました。現在はGesture Handler側のGestureAPIでジェスチャを組み立て、そのコールバック内で共有値を書き換えます。コールバックはworkletとして走るため、値の更新からスタイル反映までUIスレッド内で完結します。

import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const pan = Gesture.Pan().onUpdate((e) => {
  offset.value = e.translationX;      // workletとしてUIスレッドで実行
}).onEnd(() => {
  offset.value = withSpring(0);
});
// GestureDetector の gesture プロパティへ pan を渡して対象を包む

3系から移す場合、書き換え対象はonGestureEventのハンドラ本体です。第2引数のコンテキストオブジェクトは無くなっているため、開始位置の保持などは共有値をもう1つ用意して置き換えます。

gesture-handler 3系への移行を急がなくてよい理由

Gesture Handlerは2026年5月28日に3.0.0が出て、旧ビルダーAPIやgestureHandlerRootHOCといった古い部品が削除されました。2026年8月19日時点の最新は3.2.1(2026年8月14日公開)です。一方でlegacyタグは2.32.0を指したままで、Expo SDK 57のバンドル定義も2.32.0側を固定しています。

つまり、Expoを使っている案件では3系へ上げる動機はまだ強くありません。素のReact Nativeで新規に立ち上げる場合も、Reanimated側の対応範囲がReact Native 0.86までである以上、ジェスチャ層だけ先行して上げても得るものは限られます。既存プロジェクトなら、SDKの更新に合わせて動く判断が費用面でも読みやすくなります。

受託開発でReanimatedを採用してよい場面と見送る場面の線引き

ここからは、受託の現場でどう線を引くかを条件付きで言い切ります。ライブラリの良し悪しではなく、案件の制約側から決める話です。

採用してよい場面は指の操作に追従する画面と長い一覧を持つ画面の描画

採用してよい条件は3つです。第1に、ドラッグ・スワイプ・ボトムシートのように指の位置がそのまま描画へつながる画面があること。この種の動きはJavaScriptスレッド経由では体感が崩れるため、UIスレッド駆動の意味がはっきり出ます。第2に、長い一覧のスクロール連動でヘッダーを縮める、といった毎フレーム更新が要る演出があること。第3に、React Native 0.83以降かつExpo SDK 57相当まで版を揃えられることです。

逆に言えば、この3条件が揃う画面が1つでもあるなら、Reanimatedを入れずに標準のAnimated APIで粘る選択は工数を膨らませます。useNativeDriverが扱えるプロパティの外へ出た瞬間に自前実装が必要になるためです。ReactとReact Nativeでスタイルの扱いがどう違うかはReactとReact Nativeの違いを描画・部品・スタイル・画面遷移の4層で比較にまとめました。

見送る判断になるのはRN版を上げられない案件と静的な画面中心の構成

見送る条件も3つあります。第1に、React Nativeの版を上げられない案件です。4系はNew Architecture専用で、旧アーキテクチャに縛られた環境では3.19.5を使うことになりますが、この版は2025年12月22日の公開を最後に更新が止まっています。止まった版へ新規に依存を増やす判断は、保守契約の期間と釣り合うかを先に確かめてください。

第2に、画面が入力フォームと一覧表示だけで構成されている業務系アプリです。画面遷移の標準アニメーション以外に動きがないなら、依存とビルド時間が増える分だけ不利になります。第3に、React Native 0.87.0のような最新版へ即座に追随する方針を採っている場合です。安定版Reanimatedの対応表は0.86までで、上端では自前の検証が必要になります。

この線引きは案件ごとの制約に左右されるため、既存アプリの版と画面構成を見ないと決めきれない部分が残ります。React Nativeそのものを続けるかどうかの判断材料はReact Nativeはオワコンか?離れの実態を更新頻度・案件数・採用状況で検証にまとめてあります。実装まで含めて任せたい場合はFlutter / React Nativeによるクロスプラットフォーム開発でご相談ください。

よくある質問

Reanimatedと標準のAnimated APIはどちらを選ぶべきですか?

始点と終点が決まっている軽い動きだけなら標準のAnimated APIで足ります。指の位置に追従する動きや、スクロール量に連動して複数のプロパティを同時に動かす画面が要件にあるなら、Reanimatedを選んでください。useNativeDriverが扱える範囲を越えた時点で、標準APIはJavaScriptスレッド経由の更新になります。

3系から4系へ上げるとき、どのくらいの改修量を見込めばよいですか?

設定ファイルとimportの書き換えは機械的で、Babelプラグインの差し替えと関数名の置換で片付きます。手が要るのはuseAnimatedGestureHandlerを使っていた箇所と、withSpringのパラメータ調整です。前者はGesture APIへの書き直し、後者はdurationの解釈が変わった分の見た目の詰め直しになります。ジェスチャ処理の本数を数えれば、おおよその規模はつかめます。

Expoを使っていますが、Reanimatedだけ最新版へ上げてもよいですか?

推奨しません。Expo SDK 57のバンドル定義はReanimated 4.5.1・worklets 0.10.1を指しており、ここから外すとネイティブ側の整合が崩れる可能性があります。Reanimatedは互換表でworkletsの版とも組で管理されているため、片方だけ動かすと組み合わせが表の外へ出ます。SDKの更新に合わせるのが安全です。

New Architectureに移行していない既存アプリでも導入できますか?

4系は導入できません。公式互換表に「Reanimated 4 works only with the React Native New Architecture」と明記されています。3系なら動きますが、3.19.5が2025年12月22日公開で更新が止まっている点は織り込んでください。なお旧アーキテクチャのBridgeはReact Native 0.82で撤去済みのため、版を上げる過程で移行は避けて通れません。

アニメーションが動かないとき、まず何を確認すればよいですか?

Babelプラグインの指定を最初に見てください。4系でReanimated側のプラグインを指したままだとworkletが変換されず、UIスレッド側で動きません。次にreact-native-workletsを入れた後でネイティブを再ビルドしたかを確かめます。スタイルの適用先がAnimated.Viewになっているか、対応表どおりの版の組み合わせかも併せて点検します。

関連記事

資料請求

RELATED POSTS 関連記事