Overview of Moti
masterframer-motion, such as mount/unmount animations, variants, sequence animations, and loop/repeat animations.repository·master·Indexed 26 days ago
https://github.com/nandorojo/motiA 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.
framer-motion, such as mount/unmount animations, variants, sequence animations, and loop/repeat animations.Moti is a universal animation package for React Native powered by Reanimated 3. Key features include:
exit props.build directory by running yarn build. The resulting files can be served by any static content hosting service.yarn buildTo 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'Moti interactions are highly performant because they trigger zero re-renders and run on the native thread. However, you can further optimize them:
useCallback: If your component re-renders frequently, wrap your animation function in useCallback to prevent the animate prop from changing.useMotiPressable, useMotiPressables, etc.) accept a dependency array as the final argument, similar to useMemo. Use this to prevent unnecessary recalculations.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-modulesconst { 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 }]],
{
// ...
}
)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'Install the moti package using your preferred package manager.
Using yarn:
yarn add motiUsing npm:
npm i moti --legacy-peer-depsIf 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 }],
}}
/>Moti requires react-native-reanimated (version 2 or 3 are both compatible) to drive animations.
react-native-reanimated.Compatibility Reference:
0.17.x requires Reanimated 2.3.0 or higher (compatible with Expo SDK 44).0.16.x is compatible with Reanimated 2.2.0 (compatible with Expo SDK 43).0.8.x and higher requires at least Reanimated v2 stable (2.0.0 or higher) (compatible with Expo starting SDK 41).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
}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;