Skip to main content

Installation

Inertia is a thin wrapper around react-native-reanimated. The Reanimated install must complete first — Inertia is a peer to it, not a replacement.

Prerequisites

  • React Native >= 0.81 (or Expo SDK 54+)
  • React >= 19
  • react-native-reanimated >= 4.0.0
  • react-native-worklets >= 0.5.0 — the worklet runtime Reanimated 4 is built on. It is a peer of both Reanimated and Inertia, so Yarn and pnpm will not install it for you.

Install

Yarn is the default. Switch tabs for npm, pnpm, or Bun — your selection persists across the docs.

yarn add @rootnative/inertia react-native-reanimated react-native-worklets

Then enable the worklets Babel plugin per the Reanimated install guide. The plugin is what transforms 'worklet'-marked functions into UI-thread code; without it, every animation crashes at runtime.

A typical babel.config.js for a managed Expo app:

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

The worklets plugin must be last in the plugins array. (react-native-reanimated/plugin still works in Reanimated 4 — it is a one-line shim that forwards to react-native-worklets/plugin — but the worklets name is the canonical one, and it's the one Inertia's own dev-time install check tells you to add.)

First animation

import { Motion } from '@rootnative/inertia'

export function FadeIn() {
return (
<Motion.View
initial={{ opacity: 0, translateY: 20 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{
opacity: { type: 'timing', duration: 200 },
translateY: { type: 'spring', tension: 180, friction: 12 },
}}
/>
)
}

Try it live

The example app runs in the iframe below — tap any screen to interact with the same primitives you'd ship in your app.

example / view

Subpath imports

Each primitive is reachable directly so apps that animate one element don't pull in the rest:

import { MotionView } from '@rootnative/inertia/view'
import { MotionText } from '@rootnative/inertia/text'
import { MotionImage } from '@rootnative/inertia/image'
import { MotionPressable } from '@rootnative/inertia/pressable'
import { MotionScrollView } from '@rootnative/inertia/scroll-view'

@rootnative/inertia is sideEffects: false, so a bundler with tree-shaking enabled (Metro 0.79+, Webpack, Rollup) will drop primitives you don't reference. The named imports above tree-shake to within ~0.1 kB of the subpath equivalents, verified per-primitive in CI.

One caveat: the Motion namespace object cannot tree-shake. import { Motion } from '@rootnative/inertia' followed by Motion.View holds the whole namespace live (it's a literal object — bundlers can't eliminate property accesses). Use it for ergonomics; reach for import { MotionView } from '@rootnative/inertia' (or the subpath) when bundle size matters.

Optional adapter packages

Three sibling packages extend Inertia for capabilities that need extra peer dependencies. The core library has no required dependency on any of them — install only what you need.

Gestures (@rootnative/inertia-gestures)

Drag / pan / swipe hooks built on react-native-gesture-handler. Compose with any Motion.* primitive via <GestureDetector>.

yarn add @rootnative/inertia-gestures react-native-gesture-handler

Then follow the react-native-gesture-handler install guide — it needs <GestureHandlerRootView> near the root of your app. See Gestures adapter for the hooks.

Gradients (@rootnative/inertia-gradients)

MotionLinearGradient wraps expo-linear-gradient with animatable colors / start / end / locations. Works in bare React Native as well as Expo.

yarn add @rootnative/inertia-gradients expo-linear-gradient

See Gradients for the primitive.

SVG (@rootnative/inertia-svg)

MotionPath wraps react-native-svg's <Path> with animatable d (path morphing on structurally-compatible paths), fill, stroke, strokeWidth, opacities, and strokeDashoffset. Works in bare React Native as well as Expo.

yarn add @rootnative/inertia-svg react-native-svg

See SVG for the primitive.

Reduced motion

Inertia respects the OS reduce-motion accessibility setting by default — no extra wiring needed. To override the default for the whole app or a subtree, see MotionConfig.