moti

The universal React Native animation library, powered by Reanimated 2.

<View from={{ opacity: 0 }} animate={{ opacity: 1 }} />

Highlights

  • Universal: works on all platforms
  • 60 FPS animations on the native thread
  • Mount/unmount animations, like framer-motion
  • Powered by Reanimated 2
  • Web support, out-of-the-box
  • Expo support
  • Intuitive API
  • Variants
  • Strong TypeScript support
  • Highly-configurable animations
  • Sequence animations
  • Loop & repeat animations

Motivation

Write once, animate anywhere.
First and foremost, I made Moti because I need animations and transitions that work well on both websites & native apps.

In my opinion, React Native has the best mental model for building products. But when it comes to designing a multi-platform product at scale, you end up using Platform.select all over the place. I consider this an anti-pattern.

If you find yourself writing Platform.OS === 'web' when building UI inside of your app, something is wrong. Platform inconsistencies should be handled by third-party libraries that provide a centralized API. That's what makes (the ideal behind) React Native's mental model so great: write once, run anywhere.

I've spent most of my open source time on such inconsistencies. For example, Dripsy encourages you to design products based on screen size, not platform.

After months of trying different animation solutions on web and native, I decided I should make my own. Then Reanimated released v2 with a hooks API, and suddenly it all made sense. What we need is a performant animation library that lets us use component props to define different animation states. Hooks shouldn't be necessary. Styles should automatically transition the way CSS transitions do.

Adding an animation should be as easy as adding a background color. It should feel like play.

I started abstracting Reanimated's hooks into a single component. Pass it plain style objects, and it does the work for you. It feels like magic, and the animations are slick.

I've used Framer Motion, React Native Animatable, React Spring, CSS transitions / keyframes throughout the years, and I wanted to combine the best of these approaches into one.

The funny part of all of this is, React web already has great solutions for animations. And yet, I'm spending my time building a solution for React Native, and then making sure it also works on web. It may seem a bit odd and circular.