react-scroll-parallax
React hooks and components for scroll-driven parallax effects, powered by the Web Animations API.
Repository Health
Technical Analysis
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 adivwith 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’sisDisabledprop - Running parallax inside a custom scroll container (not just the window) via the provider’s
scrollContainerprop
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.
Used by 2 apps in this directory
Cap
Team Chat · Video Conferencing
Open source Loom alternative with GPU-accelerated recording, instant share links, AI summaries, and full self-hosting via Docker Compose.
Plasmic
CMS · Low Code Platforms · No Code Platforms
The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.