
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-native-motionify
Advanced tools
A lightweight library for smooth, scroll-driven UI with Reanimated 3.
A lightweight, production-ready toolkit for smooth, scroll-driven UI with Reanimated 3.
https://github.com/user-attachments/assets/133b5ddf-9a9a-48a1-9697-ab40de0534a1
# npm
npm install react-native-motionify
# yarn
yarn add react-native-motionify
# pnpm
pnpm add react-native-motionify
# bun
bun add react-native-motionify
# peer deps
npm install react-native-reanimated@^3.0.0
Follow Reanimated 3 setup: https://docs.swmansion.com/react-native-reanimated/docs/3.x/fundamentals/getting-started.
import { MotionifyProvider } from "react-native-motionify";
export default function App() {
return (
<MotionifyProvider threshold={8} supportIdle={false}>
<YourApp />
</MotionifyProvider>
);
}
import { ScrollView, Text, View } from "react-native";
import { useMotionify } from "react-native-motionify";
function Screen() {
const { onScroll, direction } = useMotionify();
return (
<ScrollView onScroll={onScroll} scrollEventThrottle={16}>
<Text>Direction: {direction}</Text>
<View style={{ height: 2000 }} />
</ScrollView>
);
}
import { MotionifyBottomTab } from "react-native-motionify";
function AppShell() {
return (
<>
<Screen />
<MotionifyBottomTab hideOn="down" translateRange={{ from: 0, to: 80 }}>
<TabBar />
</MotionifyBottomTab>
</>
);
}
Any screen that participates in motionify behavior must attach the onScroll from useMotionify() to its ScrollView/FlatList/SectionList and set scrollEventThrottle={16}.
// ScrollView example
const { onScroll } = useMotionify();
<ScrollView onScroll={onScroll} scrollEventThrottle={16} />;
// FlatList example
const { onScroll } = useMotionify();
<FlatList
data={items}
keyExtractor={(it) => it.id}
renderItem={renderItem}
onScroll={onScroll}
scrollEventThrottle={16}
/>;
// FlashList (shopify/flash-list) example
import { FlashList } from "@shopify/flash-list";
const { onScroll } = useMotionify();
<FlashList
data={items}
renderItem={renderItem}
estimatedItemSize={72}
onScroll={onScroll}
scrollEventThrottle={16}
/>;
// LegendList example
import { LegendList } from "legendapp-ui";
const { onScroll } = useMotionify();
<LegendList
data={items}
renderItem={renderItem}
onScroll={onScroll}
scrollEventThrottle={16}
/>;
Use this when you only need views to react to scroll (e.g., headers, FABs, content blocks).
import { ScrollView } from "react-native";
import {
MotionifyProvider,
useMotionify,
MotionifyView,
} from "react-native-motionify";
function Screen() {
const { onScroll } = useMotionify();
return (
<ScrollView onScroll={onScroll} scrollEventThrottle={16}>
{/* content */}
<MotionifyView
animatedY
hideOn="down"
translateRange={{ from: 0, to: 60 }}
>
<FAB />
</MotionifyView>
</ScrollView>
);
}
export default function App() {
return (
<MotionifyProvider>
<Screen />
</MotionifyProvider>
);
}
Note: Attach onScroll only once per scrollable container. Child motionify components consume context automatically.
Use this when you want a bottom tab to hide/show with scroll.
import {
MotionifyProvider,
MotionifyBottomTab,
useMotionify,
} from "react-native-motionify";
function Screen() {
const { onScroll } = useMotionify();
return (
<ScrollView onScroll={onScroll} scrollEventThrottle={16}>
{/* content */}
</ScrollView>
);
}
function AppShell() {
return (
<>
<Screen />
<MotionifyBottomTab hideOn="down" translateRange={{ from: 0, to: 80 }}>
<TabBar />
</MotionifyBottomTab>
</>
);
}
export default function App() {
return (
<MotionifyProvider>
<AppShell />
</MotionifyProvider>
);
}
Notes:
onScroll.exclude and currentId on MotionifyBottomTab to keep the tab visible on specific routes.tabBar.show() when navigating programmatically to ensure tab bar is visible.<MotionifyProvider threshold={8} supportIdle={false}>
idle after inactivityuseMotionify(config?)
Returns:
ScrollView/FlatListOptional config: { threshold?: number; supportIdle?: boolean }
Use tabBar object from useMotionify() to programmatically control tab bar visibility:
const { tabBar } = useMotionify();
// Show tab bar programmatically
tabBar.show();
// Hide tab bar programmatically
tabBar.hide();
// Reset to default scroll-based behavior
tabBar.reset();
Use case: When navigating between tabs programmatically (e.g., from a CTA button), the tab bar may remain hidden. Call tabBar.show() to ensure it appears:
function HomeScreen() {
const { onScroll, tabBar } = useMotionify();
const navigation = useNavigation();
const goToRewards = () => {
// Show tab bar before navigating
tabBar.show();
navigation.navigate('Rewards');
};
return (
<ScrollView onScroll={onScroll} scrollEventThrottle={16}>
{/* content */}
<Button title="Go to Rewards" onPress={goToRewards} />
</ScrollView>
);
}
<MotionifyView>
animatedY?, fadeScale?, customEffects?, hideOn='down'|'up', translateRange={from,to}, animationDuration, supportIdle, easing<MotionifyViewWithInterpolation>
interpolations, value?, customAnimatedStyle?<MotionifyBottomTab>
hideOn, translateRange, animationDuration, supportIdle, exclude?, currentId?<MotionifyBottomTabWithInterpolation>
inputRange, outputRange, extrapolate, scrollValue?DEFAULTS: threshold, durations, idle timeout, throttleTRANSLATION_PRESETS: common ranges (e.g., BOTTOM_TAB, FAB_*, HEADER)INTERPOLATION_PRESETS: fade/scale/parallax/rotate/sticky presetscreateInterpolation, createFadeInterpolation, createScaleInterpolation, createParallaxInterpolation, createRotationInterpolation, clamp, lerp, mapRange<MotionifyProvider>
<Screen />
<MotionifyBottomTab hideOn="down" translateRange={{ from: 0, to: 80 }}>
<TabBar />
</MotionifyBottomTab>
</MotionifyProvider>
When user scrolls down, the tab bar hides. If you navigate to another tab programmatically (e.g., via CTA button), the tab bar may remain hidden. Use tabBar.show() to fix this:
import { useNavigation } from '@react-navigation/native';
import { useMotionify } from 'react-native-motionify';
function HomeScreen() {
const { onScroll, tabBar } = useMotionify();
const navigation = useNavigation();
const goToRewards = () => {
// Ensure tab bar is visible before navigating
tabBar.show();
navigation.navigate('Rewards');
};
return (
<ScrollView onScroll={onScroll} scrollEventThrottle={16}>
<Text>Home Content</Text>
{/* CTA Button that navigates to another tab */}
<Button title="View Rewards" onPress={goToRewards} />
</ScrollView>
);
}
// In your tab navigator, the tab bar stays hidden until show() is called
function AppShell() {
return (
<MotionifyProvider>
<Tab.Navigator tabBar={(props) => (
<MotionifyBottomTab
hideOn="down"
translateRange={{ from: 0, to: 80 }}
>
<TabBar {...props} />
</MotionifyBottomTab>
)}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Rewards" component={RewardsScreen} />
</Tab.Navigator>
</MotionifyProvider>
);
}
<MotionifyViewWithInterpolation
interpolations={{
translateY: {
inputRange: [0, 200],
outputRange: [0, -100],
extrapolate: "extend",
},
opacity: { inputRange: [0, 150, 200], outputRange: [1, 0.5, 0] },
}}
>
<Image source={headerImage} />
</MotionifyViewWithInterpolation>
const { onScroll } = useMotionify({ threshold: 20 });
<MotionifyView fadeScale hideOn="down" animationDuration={400}>
<FAB />
</MotionifyView>;
You can skip MotionifyView/MotionifyBottomTab and drive your own Animated.* components using values from the hook.
import Animated, {
useAnimatedStyle,
interpolate,
Extrapolation,
} from "react-native-reanimated";
import { useMotionify } from "react-native-motionify";
function CustomScreen() {
const { onScroll, scrollY, directionShared } = useMotionify();
const animatedHeaderStyle = useAnimatedStyle(() => {
const translateY = interpolate(
scrollY.value,
[0, 200],
[0, -100],
Extrapolation.CLAMP
);
const opacity = directionShared.value === "down" ? 0.7 : 1;
return { transform: [{ translateY }], opacity };
});
return (
<Animated.ScrollView onScroll={onScroll} scrollEventThrottle={16}>
<Animated.View style={animatedHeaderStyle}>
<Header />
</Animated.View>
<Content />
</Animated.ScrollView>
);
}
Notes:
scrollY and/or directionShared to derive your own animations.Animated.ScrollView, Animated.FlatList, or any Animated.View.MotionifyProvider once.useMotionify() and wire onScroll + scrollEventThrottle={16}.MotionifyView for direction-based effects.MotionifyBottomTab (optionally with exclude/currentId).scrollY/directionShared with Reanimated styles.scrollEventThrottle={16}LegendList, FlashList or FlatList for long contentTo contribute to this library:
react-native-motionify.MIT
FAQs
A lightweight library for smooth, scroll-driven UI with Reanimated 3.
The npm package react-native-motionify receives a total of 7 weekly downloads. As such, react-native-motionify popularity was classified as not popular.
We found that react-native-motionify demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.