Moti Documentation

repository·master·Indexed 26 days ago

https://github.com/nandorojo/moti

A universal React Native animation library powered by Reanimated 3, providing a high-performance API for 60 FPS animations across mobile and web platforms. Moti supports mount/unmount animations via AnimatePresence, variants through useAnimationState, sequence animations, and looping. It includes specialized components like MotiView and MotiText, as well as utilities like motify() and motifySvg() to transform standard React Native and SVG components into animated moti components.

Tokens
26K
Snippets
86
Records
126
Agent score
86%

What's inside Moti

  1. Overview of Moti

    master
    Moti is a universal React Native animation library powered by Reanimated 3. It provides an intuitive API for creating 60 FPS animations on the native thread across all platforms, including web and Expo. It supports features similar to framer-motion, such as mount/unmount animations, variants, sequence animations, and loop/repeat animations.
  2. Overview of Moti features

    master

    Moti is a universal animation package for React Native powered by Reanimated 3. Key features include:

    • Universal Support: Works on all platforms including Web, Expo, and Next.js.
    • High Performance: 60 FPS animations running on the native thread.
    • Framer Motion-like API: Supports mount/unmount animations via exit props.
    • Advanced Animation Types: Supports variants, keyframes, sequences, loops, and repeats.
    • Developer Experience: Strong TypeScript support and an intuitive API that uses plain style objects to drive animations.
  3. Configure Reanimated and Gesture Handler imports

    master

    To ensure animations work correctly, add the following imports to the top of your App.tsx file:

    Note: If you are using Next.js or Solito, do NOT add these imports to your _app.tsx.

    import 'react-native-reanimated'
    import 'react-native-gesture-handler'
  4. Optimize Moti Interaction performance

    master

    Moti interactions are highly performant because they trigger zero re-renders and run on the native thread. However, you can further optimize them:

    1. Use useCallback: If your component re-renders frequently, wrap your animation function in useCallback to prevent the animate prop from changing.
    2. Dependency Arrays: All interaction hooks (useMotiPressable, useMotiPressables, etc.) accept a dependency array as the final argument, similar to useMemo. Use this to prevent unnecessary recalculations.
  5. Configure Moti for Next.js transpilation

    master

    To use Moti in a Next.js application, you must add moti to your transpiled modules using next-transpile-modules. This ensures that the Moti package is correctly processed by Next.js.

    yarn add next-transpile-modules
    const { withExpo } = require('@expo/next-adapter')
    const withFonts = require('next-fonts')
    const withImages = require('next-images')
    const withPlugins = require('next-compose-plugins')
    
    const withTM = require('next-transpile-modules')(['moti']) 
    module.exports = withPlugins(
      [withTM, withFonts, withImages, [withExpo, { projectRoot: __dirname }]],
      {
        // ...
      }
    )
  6. Import Moti components

    master

    Moti exports standard React Native component wrappers that support animation props. You can import these components directly from the moti package to use them in your React Native application.

    import { MotiView, MotiText, MotiScrollView, MotiSafeAreaView, MotiImage } from 'moti'
  7. Use multiple transforms with Reanimated 2.2 or older

    master

    If you are using Reanimated 2.2 or older, you must use the transform array syntax when applying more than one transform (e.g., combining scale and translateY). Direct property application only works for a single transform in these older versions.

    When using arrays, ensure the order of elements in the from array matches the order in the animate array.

    // ✅ Correct for Reanimated <= 2.2: use an array
    <MotiView
      from={{
        transform: [
          { scale: 0 },
          { translateY: -10 },
        ],
      }}
      animate={{
        transform: [{ scale: 1 }, { translateY: 0 }],
      }}
    />
  8. Install Reanimated 3+

    master

    Moti requires react-native-reanimated (version 2 or 3 are both compatible) to drive animations.

    Compatibility Reference:

    • Moti 0.17.x requires Reanimated 2.3.0 or higher (compatible with Expo SDK 44).
    • Moti 0.16.x is compatible with Reanimated 2.2.0 (compatible with Expo SDK 43).
    • Moti 0.8.x and higher requires at least Reanimated v2 stable (2.0.0 or higher) (compatible with Expo starting SDK 41).
  9. Configure Vanilla React Native Web with Webpack

    master

    For Vanilla React Native Web projects, you may need a custom webpack.config.js that exports the config from @expo/webpack-config. Ensure you include moti in the dangerouslyAddModulePathsToTranspile option and alias framer-motion to its distribution path.

    const createExpoWebpackConfigAsync = require('@expo/webpack-config')
    
    module.exports = async function (env, argv) {
      const config = await createExpoWebpackConfigAsync(
        {
          ...env,
          // for moti 0.19+, you can remove @motify here
          babel: { dangerouslyAddModulePathsToTranspile: ['moti', '@motify'] },
        },
        argv
      )
    
      config.resolve.alias['framer-motion'] = 'framer-motion/dist/framer-motion'
    
      return config
    }
  10. Configure Expo Router / Metro Web for Moti

    master

    To use Moti with Expo Router or Metro on Web, you must add mjs to your sourceExts in your metro.config.js file.

    const { getDefaultConfig } = require('expo/metro-config');
    
    const config = getDefaultConfig(__dirname);
    
    config.resolver.assetExts.push(
      'mjs'
    );
    
    module.exports = config;