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

Install

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

yarn add @onlynative/inertia react-native-reanimated

Then enable the Reanimated Babel plugin per its 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-reanimated/plugin'],
}
}

The Reanimated plugin must be last in the plugins array.

First animation

import { Motion } from '@onlynative/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 '@onlynative/inertia/view'
import { MotionText } from '@onlynative/inertia/text'
import { MotionImage } from '@onlynative/inertia/image'
import { MotionPressable } from '@onlynative/inertia/pressable'
import { MotionScrollView } from '@onlynative/inertia/scroll-view'

@onlynative/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 '@onlynative/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 '@onlynative/inertia' (or the subpath) when bundle size matters.

Optional adapter packages

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

Gestures (@onlynative/inertia-gestures)

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

yarn add @onlynative/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 (@onlynative/inertia-gradients)

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

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

See Gradients for the primitive.

SVG (@onlynative/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 @onlynative/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.