react-scroll-parallax

React hooks and components for scroll-driven parallax effects, powered by the Web Animations API.

Library
npm
v3.5.0
2,986stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity48
Maintenance48
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality78
Innovation82
Learning Curve65

react-scroll-parallax gives React developers a hook (useParallax) and a set of components (Parallax, ParallaxBanner, ParallaxProvider) for adding scroll-driven parallax motion to banners, images, or any other DOM element. Rather than reimplementing scroll-position math on every project, it delegates the actual animation engine to a companion package, parallax-controller, which drives each element with a ScrollTimeline or ViewTimeline via the Web Animations API — keeping the animation on the compositor instead of blocking the main thread on scroll events.

A single ParallaxProvider at the root of an app creates and owns one controller instance for the whole tree, and every useParallax call (or Parallax/ParallaxBanner component) registers an element against that shared controller, applying translate, rotate, scale, and opacity keyframes tied to scroll progress. The library has shipped since 2017, has gone through several major versions, and is in the middle of a v4 beta rewrite that moves the underlying engine onto native browser scroll-driven animations.

What You Get

  • useParallax() hook that returns a ref plus the underlying controller/element, for building fully custom parallax behavior
  • <Parallax> component that wraps a div with parallax props for a declarative, no-hook-required API
  • <ParallaxBanner> component for layered banner/hero effects with multiple parallax layers
  • <ParallaxProvider> that creates and shares a single parallax-controller instance across the whole component tree via context
  • TypeScript types re-exported from the underlying parallax-controller engine (e.g. EasingParam)
  • A dual ESM/CJS build (via tsdown) with bundled type declarations, kept under a 10KB size-limit budget for each format

Common Use Cases

  • Adding parallax motion to hero banners and marketing pages without hand-writing scroll listeners
  • Layering background/foreground images at different scroll speeds inside a ParallaxBanner
  • Applying scroll-triggered rotate/scale/opacity transitions to individual page sections via useParallax
  • Disabling or re-enabling parallax globally (e.g. for reduced-motion preferences) through ParallaxProvider’s isDisabled prop
  • Running parallax inside a custom scroll container (not just the window) via the provider’s scrollContainer prop

Under The Hood

Architecture The entry point (src/index.ts) re-exports three component modules, the hooks module, and a shared ParallaxContext. ParallaxProvider (src/components/ParallaxProvider/ParallaxProvider.tsx) lazily creates one ParallaxController instance via a createController helper on first render and exposes it through a plain React.createContext<ParallaxController | null>(null); effects there sync scrollContainer and isDisabled prop changes into the controller and destroy it on unmount. useParallax (src/hooks/useParallax.ts) is the real integration point: it pulls the controller out of context, creates a parallax-controller Element bound to a DOM ref on mount, and pushes prop updates through controller.updateElementPropsById in a dependency-heavy effect covering every parallax prop. Parallax and ParallaxBanner are thin wrappers around this hook that render a div and spread through non-parallax props, with getIsolatedParallaxProps acting as the single shared boundary that splits parallax-specific props (speed, rotate*, scale*, translate*, easing, etc.) from arbitrary passthrough DOM props. It’s a deliberately thin React binding layer — nearly all of the actual scroll-timeline/animation logic lives in the separate parallax-controller package this library depends on.

Tech Stack Written in TypeScript, with a single runtime dependency (parallax-controller ^2.0.0-beta.0, a separate package by the same author that implements the Web Animations API / ScrollTimeline engine) and peer dependencies on React and React DOM (supporting everything from 16.8 through 19). Built with tsdown (an esbuild-based bundler) into dual ESM/CJS output with generated .d.mts/.d.cts declaration files, gated by a size-limit budget of 10KB per format. Tests run on Vitest with @testing-library/react, @testing-library/jest-dom, and jsdom; linting uses ESLint 9’s flat config with typescript-eslint; Storybook 10 hosts interactive component demos and a Docusaurus-based documentation/ site backs the public docs. CI (GitHub Actions) runs lint, test, and build across Node 24 on Ubuntu and macOS, and a Husky pre-commit hook re-runs lint locally.

Code Quality Each component directory (Parallax, ParallaxBanner, ParallaxProvider) and both hooks (useParallax, useParallaxController) ship their own *.test.tsx file, several backed by Jest/Vitest snapshot tests in __snapshots__ directories, and a Codecov badge in the README implies coverage is tracked in CI. Error handling is explicit where it matters most — useParallax throws a descriptive Error if its ref isn’t attached to an HTMLElement rather than failing silently. Naming is consistent and narrowly scoped (getIsolatedParallaxProps, removeUndefinedObjectKeys), and props are fully typed through shared ParallaxProps/ParallaxProviderProps type modules. The project is linted and type-checked in CI on every push, so regressions in either area are caught before merge.

API Design The library offers both a hook and declarative components for the same underlying behavior, so consumers can pick whichever fits their component style rather than being forced into one pattern. Parallax props map closely to familiar CSS transform axes (rotateX/Y/Z, scaleX/Y/Z, translateX/Y, speed, opacity, easing), which keeps the learning curve low for anyone who already knows CSS transforms. ParallaxProvider absorbs all controller lifecycle management (creation, scroll-container updates, disable/enable, teardown) so application code never touches the underlying engine directly. The project also publishes a migration guide for its v3→v4 beta transition and an llms.txt documentation endpoint, showing active attention to both human and LLM-assisted consumers of the docs.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search