React Parallax

iampoul1 pts0 comments

@iampoul/react-parallax

zero dependencies<br>rAF-based<br>TypeScript<br>a11y ready<br>npm package<br>react-parallax<br>Scroll and pointer parallax for React. One container, unlimited layers. Move your cursor.<br>zero depsrAF-basedTypeScripta11y ready<br>npm i @iampoul/react-parallaxGitHub →<br>v0.7.0|MIT|React ≥18

Get started<br>Installation<br>npmpnpmyarnbun<br>npm install @iampoul/react-parallaxcopy

Zero dependencies — Only a React peer dependency required<br>Performant — Single rAF loop — layers update via refs, no re-renders<br>Accessible — Auto-pauses for prefers-reduced-motion<br>Flexible — Scroll, pointer, or both. Per-layer speed, rotate, scale, fade, blur<br>TypeScript — Full type definitions included

scene.tsxcopy<br>import { Parallax, ParallaxLayer } from "@iampoul/react-parallax"

export function Scene() {<br>return (<br>Parallax<br>mode="both"<br>intensity={1}<br>springConfig={{ stiffness: 120, damping: 14 }}<br>onProgress={({ scrollProgress }) => {<br>console.log("scroll:", scrollProgress)<br>}}<br>{/* Background — slower, blurs at scroll edges */}<br>ParallaxLayer speed={0.5} pointerStrength={20} blur={4} scrollRange="20%"><br>img src="/bg.png" alt="" /><br>ParallaxLayer>

{/* Foreground — faster, always slightly soft */}<br>ParallaxLayer speed={-0.3} pointerStrength={40} blurBase={2} zIndex={1}><br>img src="/fg.png" alt="" /><br>ParallaxLayer><br>Parallax>

Examples<br>Demos<br>Scroll depth<br>Layers with different speed values create depth as you scroll. Positive values recede into the background, negative values come forward. As of v0.5.0, scrollRange also accepts a percentage string like "20%" to scale travel with the container height.

scroll to see depth

copy<br>Parallax mode="scroll" intensity={1} smoothing={0.1}><br>ParallaxLayer speed={0.7} scrollRange={80}>…far…ParallaxLayer><br>ParallaxLayer speed={0.35} scrollRange={80}>…mid…ParallaxLayer><br>ParallaxLayer speed={-0.4} scrollRange={80}>…close…ParallaxLayer><br>Parallax>

{/* v0.5.0: scrollRange also accepts % of container height */}<br>{/* */}

Pointer tilt<br>pointerStrength controls how far each layer shifts in response to the cursor. Higher values create more dramatic parallax.

move cursor here

copy<br>Parallax mode="pointer" intensity={1.2} smoothing={0.07}><br>ParallaxLayer pointerStrength={12}>…ParallaxLayer><br>ParallaxLayer pointerStrength={28}>…ParallaxLayer><br>ParallaxLayer pointerStrength={50}>…ParallaxLayer><br>ParallaxLayer pointerStrength={80}>…ParallaxLayer><br>Parallax>

Rotate, scale & fade<br>Combine rotate, scale, and fade on layers for richer scroll transitions.

scroll to see transforms

copy<br>Parallax mode="scroll" intensity={1} smoothing={0.1}><br>ParallaxLayer speed={0.2} rotate={120} scrollRange={100} /><br>ParallaxLayer speed={-0.3} rotate={-80} scale={0.3} scrollRange={100} /><br>ParallaxLayer speed={0.5} fade={0.2} scrollRange={100} /><br>Parallax>

Blur depth-of-fieldv0.2.0<br>The blur prop applies a dynamic blur() CSS filter — sharp at scroll center, soft toward the edges. Like a camera pulling focus.

scroll to pull focus

copy<br>Parallax mode="scroll" intensity={1} smoothing={0.1}><br>{/* Far — blurs out at scroll edges */}<br>ParallaxLayer speed={0.6} blur={10} scrollRange={90} /><br>{/* Mid — subtle blur */}<br>ParallaxLayer speed={0.25} blur={5} scrollRange={90} /><br>{/* Near — always sharp */}<br>ParallaxLayer speed={-0.3} blur={0} scrollRange={90} /><br>Parallax>

Always-soft backgroundv0.2.0<br>blurBase applies a constant blur at all scroll positions — perfect for soft atmospheric backgrounds. Composes with blur: total = blurBase + |scroll| × blur.

move cursor & scroll

copy<br>Parallax mode="both" intensity={1} smoothing={0.09}><br>{/* Always blurred — soft atmospheric background */}<br>ParallaxLayer speed={0.5} blurBase={5} scrollRange={80}><br>div className="size-40 rounded-full bg-foreground/10" /><br>ParallaxLayer><br>{/* Blurred + gets softer toward scroll edges */}<br>ParallaxLayer speed={0.2} blurBase={3} blur={4} scrollRange={80}><br>div className="size-24 rounded-3xl bg-foreground/20" /><br>ParallaxLayer><br>{/* Sharp focal point */}<br>ParallaxLayer speed={-0.15} scrollRange={80}><br>div className="size-8 rounded-lg bg-foreground" /><br>ParallaxLayer><br>Parallax>

Overflow visiblev0.4.0<br>By default the container clips children with overflow: hidden. Set overflow="visible" to let layers drift outside the container bounds — great for floating elements that extend beyond their section.

move cursor here

copy<br>{/* overflow="visible" lets layers drift outside container bounds */}<br>Parallax<br>mode="pointer"<br>overflow="visible"<br>smoothing={0.07}<br>{/* bleeds left */}<br>ParallaxLayer pointerStrength={60} className="absolute -left-8 top-1/2">…ParallaxLayer><br>{/* bleeds right */}<br>ParallaxLayer pointerStrength={-50} className="absolute -right-8 top-1/2">…ParallaxLayer><br>{/* center — counter-drifts */}<br>ParallaxLayer pointerStrength={-20}>…ParallaxLayer><br>Parallax>

Horizontal scrollv0.7.0<br>Set direction="horizontal" to drive scroll progress left-to-right instead of top-to-bottom — perfect for side-scrolling timelines, carousels, and panoramas. Pair with axis="x" on layers and scrollParent pointing to the scrollable...

parallaxlayer parallax scroll speed scrollrange blur

Related Articles