A React Native animation library for revealing children components with beautiful puff and pop effects
npm install react-native-puff-popA React Native animation library for revealing children components with beautiful puff and pop effects.
Works with both React Native CLI and Expo projects - no native dependencies required!

- ðŽ 16 Animation Effects: scale, rotate, fade, slideUp/Down/Left/Right, bounce, flip, zoom, rotateScale, shake, pulse, swing, wobble, elastic
- ðŊ Exit Animations: Different effects for enter and exit animations
- ð Reverse Mode: Reverse animation direction with a single prop
- ðïļ Custom Initial Values: Fine-tune starting opacity, scale, rotation, and position
- ð Animation Intensity: Control how dramatic your animations are (0-1)
- ð Anchor Point: Set transform origin for scale/rotate (top, bottom, corners, etc.)
- ð§ē Spring Physics: Use physics-based spring animations with customizable tension/friction
- ðĶī Skeleton Mode: Reserve space before animation or expand from zero height
- ⥠Native Driver Support: Smooth 60fps animations
- ðŊ Easy to Use: Just wrap your components with
- ðą Cross Platform: Works on iOS, Android, and Web
- ð§ TypeScript: Full TypeScript support with type definitions
``bashUsing npm
npm install react-native-puff-pop
Usage
$3
`tsx
import { PuffPop } from 'react-native-puff-pop';function App() {
return (
Hello, PuffPop!
);
}
`$3
`tsx
// Scale from center (default)
// Rotate while appearing
// Rotate + Scale combined
// Bounce effect
// Slide from bottom
// 3D Flip effect
`$3
By default,
skeleton={true} reserves space for the component before animation:`tsx
// Reserves space (default)
// Expands from zero height, pushing content below
`$3
Use
PuffPopGroup for easy staggered animations:`tsx
import { PuffPopGroup } from 'react-native-puff-pop';// Simple stagger
// With different directions
// Horizontal layout with gap
`Or use manual delays with
PuffPop:`tsx
`$3
`tsx
function App() {
const [visible, setVisible] = useState(false); return (
<>
`$3
`tsx
// Loop infinitely
// Loop 3 times
// Loop with delay between iterations
`$3
Use different effects for enter and exit animations:
`tsx
// Scale in, fade out
effect="scale"
exitEffect="fade"
visible={isVisible}
>
// Slide up to enter, slide down to exit
effect="slideUp"
exitEffect="slideDown"
exitDuration={200}
visible={isVisible}
>
// Different timing for enter and exit
effect="zoom"
duration={400}
easing="spring"
exitEffect="fade"
exitDuration={150}
exitEasing="easeIn"
exitDelay={50}
visible={isVisible}
>
`With
PuffPopGroup:`tsx
effect="slideUp"
exitEffect="fade"
exitDuration={150}
staggerDelay={50}
visible={isVisible}
>
`$3
Stagger the exit animation of group children:
`tsx
// Children exit one by one in reverse order (last first)
staggerDelay={50}
exitStaggerDelay={50}
exitStaggerDirection="reverse"
visible={isVisible}
>
// Children exit from center outward
exitStaggerDelay={30}
exitStaggerDirection="center"
visible={isVisible}
>
`Exit stagger directions:
-
forward: First child exits first
- reverse: Last child exits first (default, LIFO)
- center: Center children exit first
- edges: Edge children exit first$3
Fine-tune the starting values of your animations:
`tsx
// Start from 50% opacity instead of 0
// Start from a larger scale
// Custom slide distance
// Combine multiple custom values
effect="rotateScale"
initialOpacity={0.3}
initialScale={0.2}
initialRotate={-90}
>
`$3
Reverse the animation direction:
`tsx
// slideUp now slides from top instead of bottom
// slideLeft now slides from left instead of right
// rotate spins clockwise instead of counter-clockwise
`With
PuffPopGroup:`tsx
`$3
Control how dramatic your animations are with the
intensity prop (0-1):`tsx
// Full animation (default)
// Half the movement distance (25px instead of 50px)
// Subtle animation (10px slide)
// No movement, just fade (intensity 0)
`Works with all effects:
`tsx
// Smaller scale range (starts at 0.5 instead of 0)
// Less rotation (180deg instead of 360deg)
`With
PuffPopGroup:`tsx
`$3
Set the transform origin for scale/rotate animations:
`tsx
// Scale from top (expands downward)
// Scale from bottom-left corner
// Rotate from top-left (door-opening effect)
// Flip from right edge
`Available anchor points:
| Value | Description |
|-------|-------------|
|
center | Default center point |
| top | Top center |
| bottom | Bottom center |
| left | Left center |
| right | Right center |
| topLeft | Top-left corner |
| topRight | Top-right corner |
| bottomLeft | Bottom-left corner |
| bottomRight | Bottom-right corner |$3
Use physics-based spring animations for more natural, bouncy effects:
`tsx
// Enable spring animation
// Customize spring physics
effect="slideUp"
useSpring
springConfig={{
tension: 150, // Higher = faster, snappier
friction: 8, // Higher = less bouncy
}}
>
// Very bouncy spring
effect="scale"
useSpring
springConfig={{
tension: 200,
friction: 5,
bounciness: 12,
}}
>
`Spring config options:
| Option | Default | Description |
|--------|---------|-------------|
|
tension | 100 | Spring stiffness (higher = faster) |
| friction | 10 | Damping (higher = less oscillation) |
| speed | 12 | Animation speed multiplier |
| bounciness | 8 | Bounce amount (higher = more bouncy) |Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
children | ReactNode | - | Children to animate |
| effect | PuffPopEffect | 'scale' | Animation effect type |
| duration | number | 400 | Animation duration in ms |
| delay | number | 0 | Delay before animation starts in ms |
| easing | PuffPopEasing | 'easeOut' | Easing function |
| skeleton | boolean | true | Reserve space before animation |
| visible | boolean | true | Control visibility |
| animateOnMount | boolean | true | Animate when component mounts |
| onAnimationStart | () => void | - | Callback when animation starts |
| onAnimationComplete | () => void | - | Callback when animation completes |
| style | ViewStyle | - | Custom container style |
| loop | boolean \| number | false | Loop animation (true=infinite, number=times) |
| loopDelay | number | 0 | Delay between loop iterations in ms |
| respectReduceMotion | boolean | true | Respect system reduce motion setting |
| testID | string | - | Test ID for testing purposes |
| exitEffect | PuffPopEffect | - | Animation effect for exit (defaults to enter effect) |
| exitDuration | number | - | Duration for exit animation (defaults to duration) |
| exitEasing | PuffPopEasing | - | Easing for exit animation (defaults to easing) |
| exitDelay | number | 0 | Delay before exit animation starts in ms |
| initialOpacity | number | - | Custom initial opacity (0-1) |
| initialScale | number | - | Custom initial scale value |
| initialRotate | number | - | Custom initial rotation in degrees |
| initialTranslateX | number | - | Custom initial X translation in pixels |
| initialTranslateY | number | - | Custom initial Y translation in pixels |
| reverse | boolean | false | Reverse animation direction |
| intensity | number | 1 | Animation intensity multiplier (0-1) |
| anchorPoint | PuffPopAnchorPoint | 'center' | Transform origin for scale/rotate |
| useSpring | boolean | false | Use physics-based spring animation |
| springConfig | PuffPopSpringConfig | - | Spring animation settings (tension, friction, etc.) |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
children | ReactNode | - | Children to animate with stagger effect |
| effect | PuffPopEffect | 'scale' | Animation effect for all children |
| duration | number | 400 | Animation duration for each child in ms |
| staggerDelay | number | 100 | Delay between each child's animation in ms |
| initialDelay | number | 0 | Delay before the first child animates in ms |
| easing | PuffPopEasing | 'easeOut' | Easing function for all children |
| skeleton | boolean | true | Reserve space before animation |
| visible | boolean | true | Control visibility of all children |
| animateOnMount | boolean | true | Animate when component mounts |
| onAnimationStart | () => void | - | Callback when first child starts animating |
| onAnimationComplete | () => void | - | Callback when all children complete |
| style | ViewStyle | - | Custom container style |
| staggerDirection | 'forward' \| 'reverse' \| 'center' \| 'edges' | 'forward' | Direction of stagger animation |
| horizontal | boolean | false | Render children in horizontal layout |
| gap | number | - | Gap between children |
| respectReduceMotion | boolean | true | Respect system reduce motion setting |
| testID | string | - | Test ID for testing purposes |
| exitEffect | PuffPopEffect | - | Exit animation effect for all children |
| exitDuration | number | - | Exit duration for all children |
| exitEasing | PuffPopEasing | - | Exit easing for all children |
| exitDelay | number | 0 | Exit delay for all children |
| initialOpacity | number | - | Custom initial opacity for all children |
| initialScale | number | - | Custom initial scale for all children |
| initialRotate | number | - | Custom initial rotation for all children |
| initialTranslateX | number | - | Custom initial X translation for all children |
| initialTranslateY | number | - | Custom initial Y translation for all children |
| reverse | boolean | false | Reverse animation direction for all children |
| intensity | number | 1 | Animation intensity multiplier for all children |
| anchorPoint | PuffPopAnchorPoint | 'center' | Transform origin for all children |
| useSpring | boolean | false | Use spring animation for all children |
| springConfig | PuffPopSpringConfig | - | Spring settings for all children |
| exitStaggerDelay | number | 0 | Delay between each child's exit animation |
| exitStaggerDirection | 'forward' \| 'reverse' \| 'center' \| 'edges' | 'reverse' | Direction of exit stagger |$3
| Effect | Description |
|--------|-------------|
|
scale | Scale from center point |
| rotate | Full rotation (360°) while appearing |
| fade | Simple fade in |
| slideUp | Slide from bottom |
| slideDown | Slide from top |
| slideLeft | Slide from right |
| slideRight | Slide from left |
| bounce | Bounce effect with overshoot |
| flip | 3D flip effect |
| zoom | Zoom with slight overshoot |
| rotateScale | Rotate + Scale combined |
| shake | Shake left-right (for alerts, errors) |
| pulse | Pulse heartbeat effect (for emphasis) |
| swing | Swing like pendulum (for menus) |
| wobble | Wobble with tilt (playful entrance) |
| elastic | Elastic stretch effect (springy feel) |$3
| Easing | Description |
|--------|-------------|
|
linear | Linear animation |
| easeIn | Slow start |
| easeOut | Slow end |
| easeInOut | Slow start and end |
| spring | Spring-like effect |
| bounce | Bouncing effect |Skeleton Mode Explained
$3
The component reserves its full space immediately, and only the visual appearance animates. This is useful when you don't want layout shifts.$3
The component's height starts at 0 and expands during animation, pushing other content below it. This creates a more dynamic entrance effect.Accessibility
PuffPop respects the system's "Reduce Motion" accessibility setting by default. When users have enabled reduce motion in their device settings, animations will be instant (0 duration) to avoid discomfort.
`tsx
// Respect reduce motion setting (default)
// Ignore reduce motion setting (always animate)
``MIT
Contributions are welcome! Please feel free to submit a Pull Request.