Get started in 3 steps
From zero to your first animation in under a minute.
Install
Add Inertia and Reanimated, then enable the Babel plugin.
yarn add @onlynative/inertia react-native-reanimatedImport
Pull in the Motion namespace — or a tree-shakable subpath.
import { Motion } from '@onlynative/inertia'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.
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.