Moti uses Reanimated 2 under the hood to drive high-performance animations on iOS, Android and Web.

Starter project#

If you're starting a project from scratch, or just want to play around, you can use the Expo + Moti starter.

npx create-react-native-app -t with-moti

Install Moti#

First, install moti in your app:

npm install moti

Install Reanimated 2#

Moti requires that you install react-native-reanimated.

Moti 0.8.x and higher requires at least Reanimated v2 stable (2.0.0 or higher). This version is compatible with Expo starting SDK 41.

If you haven't upgraded Reanimated past 2.0.0-rc.0, you can also use Moti 0.7.x. However, I recommend upgrading to get the latest features/fixes.

If you're using Expo#

Please follow the Expo instructions for installing react-native-reanimated v2.

You'll need at least Expo SDK 40, but I recommend using SDK 41.

If you aren't using Expo#

Please follow Reanimated's installation instructions for v2.

Web support#

Please see the following guides:

Hermes/Android Support#

Moti uses Proxy under the hood, which is not supported on older versions of Hermes (see hermes#33). Follow the steps below if you're using Hermes.

If you're using React Native 0.63.x#

Install v0.5.2-rc.1 of Hermes:

npm install hermes-engine@v0.5.2-rc1

Relevant release notes for v0.5.2-rc1 here.

If you're using React Native 0.64.x#

Upgrade Hermes to 0.7.*.

Possible error#

As mentioned in this Moti issue, if you don't install the correct version of Hermes, you might see this error:

Property 'Proxy' doesn't exist, js engine: hermes [Mon Feb 08 2021 19:21:54.427] ERROR Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication), js engine: hermes

Using inline requires#

If you're using Inline Requires, you might need to import react-native-reanimated in the root of your app before using any Moti code.

// App.js
import 'react-native-reanimated'

Only do this if you notice your app isn't working with Moti and you have inline requires enabled.

Create your first animation#

import { View as MotiView } from 'moti'
export const FadeIn = () => (
from={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ type: 'timing' }}

Your component will now fade in on the native thread at 60 FPS.