npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@allwells/react-scroll-reveal

v1.0.4

Published

Production-ready, type-safe scroll animation library for React

Readme

React Scroll Reveal

A production-ready, type-safe scroll animation library for React applications. Reveal elements with beautiful animations as they enter the viewport using IntersectionObserver, with support for GSAP, Framer Motion, and Headless UI.

npm version Bundle Size TypeScript License: MIT

Features

  • 🎨 20+ Built-in Animations - Fade, slide, zoom, rotate, flip, and more
  • 🚀 Multiple Animation Engines - Choose between Framer Motion, GSAP, or Headless UI
  • 📦 Tree-Shakable - Only bundle what you use
  • 🔒 Fully Type-Safe - Written in TypeScript with strict typing
  • Performance Optimized - Efficient IntersectionObserver usage with batching
  • 🌐 SSR Compatible - Works with Next.js, Gatsby, and other SSR frameworks
  • Accessibility First - Respects prefers-reduced-motion
  • 🎛️ Highly Configurable - Global config, custom animations, and fine control
  • 🪝 Hooks API - Use animations programmatically
  • 📱 Responsive - Works on all devices and screen sizes

Installation

npm install @allwells/react-scroll-reveal framer-motion gsap @headlessui/react
# or
yarn add @allwells/react-scroll-reveal framer-motion gsap @headlessui/react
# or
pnpm add @allwells/react-scroll-reveal framer-motion gsap @headlessui/react

Quick Start

import { ScrollReveal } from '@allwells/react-scroll-reveal';

function App() {
  return (
    <ScrollReveal animationType="fadeUp" delay={200}>
      <h1>Hello World!</h1>
    </ScrollReveal>
  );
}

Animation Types

| Animation | Description | |-----------|-------------| | fade | Simple fade in | | fadeUp | Fade in from bottom | | fadeDown | Fade in from top | | fadeLeft | Fade in from right | | fadeRight | Fade in from left | | slideUp | Slide in from bottom | | slideDown | Slide in from top | | slideLeft | Slide in from right | | slideRight | Slide in from left | | zoom | Scale from 0.8 to 1 | | zoomIn | Scale from 0 to 1 | | zoomOut | Scale from 1.2 to 1 | | rotate | Rotate 180 degrees | | rotateLeft | Rotate from -90 degrees | | rotateRight | Rotate from 90 degrees | | flip | 3D flip on Y axis | | flipX | 3D flip on X axis | | flipY | 3D flip on Y axis | | blur | Blur effect | | bounce | Bounce animation |

Basic Usage

Simple Animation

<ScrollReveal animationType="fade">
  <div>This will fade in</div>
</ScrollReveal>

With Options

<ScrollReveal
  animationType="slideUp"
  delay={300}
  duration={800}
  once={false}
  threshold={0.2}
>
  <Card>
    <h2>Animated Card</h2>
    <p>This slides up every time it enters the viewport</p>
  </Card>
</ScrollReveal>

Custom Animation

<ScrollReveal
  customAnimation={{
    initial: { opacity: 0, scale: 0.5, rotate: -180 },
    animate: { opacity: 1, scale: 1, rotate: 0 }
  }}
  duration={1000}
>
  <div>Custom animated element</div>
</ScrollReveal>

Global Configuration

Wrap your app with ScrollRevealProvider to set default options:

import { ScrollRevealProvider } from '@allwells/react-scroll-reveal';

function App() {
  return (
    <ScrollRevealProvider
      config={{
        animationType: 'fadeUp',
        duration: 600,
        delay: 100,
        once: true,
        threshold: 0.15,
        respectReducedMotion: true
      }}
    >
      <YourApp />
    </ScrollRevealProvider>
  );
}

Using Different Animation Engines

Framer Motion (Default)

<ScrollReveal animationType="fade" engine="framer">
  <div>Animated with Framer Motion</div>
</ScrollReveal>

GSAP

<ScrollReveal animationType="slideUp" engine="gsap">
  <div>Animated with GSAP</div>
</ScrollReveal>

Headless UI

<ScrollReveal animationType="zoom" engine="headless">
  <div>Animated with Headless UI Transition</div>
</ScrollReveal>

Hooks API

useScrollReveal

For programmatic control:

import { useScrollReveal } from '@allwells/react-scroll-reveal';

function Component() {
  const ref = useRef<HTMLDivElement>(null);
  const { isInView, hasAnimated, reveal, hide, reset } = useScrollReveal({
    ref,
    threshold: 0.1,
    once: true
  });

  return (
    <div ref={ref}>
      {isInView ? 'In view!' : 'Not in view'}
      <button onClick={reveal}>Reveal</button>
      <button onClick={hide}>Hide</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

useScrollRevealControls

Control multiple elements:

import { useScrollRevealControls } from '@allwells/react-scroll-reveal';

function Controller() {
  const controls = useScrollRevealControls();

  return (
    <div>
      <button onClick={() => controls.revealAll('.reveal-item')}>
        Reveal All
      </button>
      <button onClick={() => controls.hideAll('.reveal-item')}>
        Hide All
      </button>
    </div>
  );
}

Advanced Examples

Staggered Animations

function StaggeredList({ items }) {
  return (
    <div>
      {items.map((item, index) => (
        <ScrollReveal
          key={item.id}
          animationType="fadeUp"
          delay={index * 100}
        >
          <ListItem>{item.text}</ListItem>
        </ScrollReveal>
      ))}
    </div>
  );
}

Combining Animations

import { combineAnimations, animationPresets } from '@allwells/react-scroll-reveal';

const customAnimation = combineAnimations(
  animationPresets.fade,
  animationPresets.slideUp,
  { initial: { scale: 0.8 }, animate: { scale: 1 } }
);

<ScrollReveal customAnimation={customAnimation}>
  <div>Combined animations</div>
</ScrollReveal>

Responsive Animations

function ResponsiveReveal({ children }) {
  const isMobile = useMediaQuery('(max-width: 768px)');
  
  return (
    <ScrollReveal
      animationType={isMobile ? 'fadeUp' : 'fadeRight'}
      duration={isMobile ? 400 : 600}
    >
      {children}
    </ScrollReveal>
  );
}

API Reference

ScrollReveal Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | - | Content to animate | | animationType | AnimationType | 'fade' | Predefined animation | | customAnimation | CustomAnimation | - | Custom animation config | | delay | number | 0 | Delay in milliseconds | | duration | number | 600 | Duration in milliseconds | | once | boolean | true | Animate only once | | threshold | number \| number[] | 0.1 | IntersectionObserver threshold | | rootMargin | string | '0px' | IntersectionObserver margin | | disabled | boolean | false | Disable animations | | engine | 'framer' \| 'gsap' \| 'headless' | 'framer' | Animation engine | | className | string | - | CSS class name | | style | CSSProperties | - | Inline styles | | onReveal | () => void | - | Callback on reveal | | onHide | () => void | - | Callback on hide |

useScrollReveal Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | ref | RefObject<Element> | - | Element reference | | threshold | number \| number[] | 0.1 | Visibility threshold | | rootMargin | string | '0px' | Root margin | | once | boolean | true | Trigger only once | | disabled | boolean | false | Disable observer | | root | Element \| null | null | Custom root element |

Performance Tips

  1. Use once={true} for elements that don't need to re-animate
  2. Batch animations with similar configurations using the provider
  3. Disable on mobile if performance is a concern:
    <ScrollReveal disabled={isMobile}>
  4. Use appropriate thresholds - higher values (0.3-0.5) for important content
  5. Limit simultaneous animations - stagger delays for lists

Browser Support

  • Chrome/Edge: ✅ Full support
  • Firefox: ✅ Full support
  • Safari: ✅ Full support (iOS 12.2+)
  • IE11: ❌ Not supported (IntersectionObserver polyfill required)

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

License

MIT © The Web Architect

Acknowledgments

Built with: