Skip to main content
v0.0.1-alpha — full v0.1 surface implemented

Inertia

Declarative animation primitives for React Native

A thin wrapper around react-native-reanimated. Animations are props on a component — no shared values, no worklets, no useAnimatedStyle boilerplate.

Get started in 3 steps

From zero to your first animation in under a minute.

01

Install

Add Inertia and Reanimated, then enable the Babel plugin.

yarn add @onlynative/inertia react-native-reanimated
02

Import

Pull in the Motion namespace — or a tree-shakable subpath.

import { Motion } from '@onlynative/inertia'
03

Animate

Express animations as props. No worklets, no shared values.

<Motion.View animate={{ opacity: 1 }} />

Why Inertia

Built to clear specific sharp edges in existing Reanimated wrappers — not aspirational, just the bar.

Props, not boilerplate

Express animations as props on a component. Shared values, worklets, and useAnimatedStyle stay hidden by default.

Per-primitive style inference

Motion.View accepts ViewStyle keys. Motion.Text accepts TextStyle. Motion.Image accepts ImageStyle. Wrong props error at compile time.

react-spring vocabulary

Springs use tension, friction, mass, velocity. Reanimated’s raw stiffness / damping never appear in the public API.

One gesture prop

pressed, focused, focusVisible, hovered on every primitive. No whileTap / whilePress soup, no separate pressable variant.

Tree-shakable subpaths

Import only what you animate via @onlynative/inertia/view, /text, /image, /pressable, /scroll-view. Bundle size is verified per primitive in CI.

Stable, memoized worklets

The factory hashes resolved animate / transition objects. Re-renders with unchanged values produce zero new UI-thread closures.

Declarative API, native feel

One animate prop, one transition prop, and a spring that runs on the UI thread. Per-property transitions, mount and exit animations, and gestures all share the same shape.

Read the Docs
FadeInCard.tsx
import { Motion } from '@onlynative/inertia'

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

Ready to animate?

Drop a Motion primitive in, hand it an animate prop, and you’re shipping.