Solid’s performance story depends on not re-rendering, so an animation library that pushed a signal update every frame would undo the thing you picked Solid for. This one never touches the reactive graph: the engine writes to the DOM directly, driven by scroll position, and the hook only hands you a ref setter.
Hook returning a ref setter
svg-scroll-draw/solid — every sample below is written against the wrappers this package actually exports.
import { useScrollDraw } from 'svg-scroll-draw/solid';
export function Hero() {
// Returns a callback ref — pass it straight to ref={}
const draw = useScrollDraw({ easing: 'ease-out', speed: 1.2, fade: true });
return (
<div ref={draw}>
<svg viewBox="0 0 200 100">
<path d="M10 50 Q 100 10 190 50" stroke="#111" fill="none" />
</svg>
</div>
);
}import { createScrollDraw } from 'svg-scroll-draw/solid';
export function Replayable() {
const [draw, getInstance] = createScrollDraw({ easing: 'ease-out' });
return (
<>
<div ref={draw}>
<svg viewBox="0 0 200 100">
<path d="M10 50 Q 100 10 190 50" stroke="#111" fill="none" />
</svg>
</div>
<button onClick={() => getInstance()?.replay()}>Replay</button>
</>
);
}import { useScrollAnimate, useScrollCounter, useScrollText }
from 'svg-scroll-draw/solid';
export function Stats() {
const card = useScrollAnimate({ from: { opacity: 0, y: 24 } });
const revenue = useScrollCounter({ to: 48000 });
const heading = useScrollText({ split: 'words', stagger: 0.05 });
return (
<>
<h2 ref={heading}>Every API, one package.</h2>
<div ref={card}><span ref={revenue}>0</span></div>
</>
);
}Worth knowing: The hook returns a callback ref rather than a signal, which is why you pass it directly to ref={} with no parentheses. Cleanup runs through onCleanup, so it works inside <Show> and <For> without leaking.
10 KB gzipped for every API at once, and each one is a separate entry point — so a page that only reveals elements ships 3.9 KB, not the lot. The equivalent GSAP stack for the same work is 47.5 KB, which makes this 4.75× smaller. GSAP is free and considerably broader; if you need timelines, Draggable or Flip, use GSAP.
Measured 2026-08-14 at gzip level 9 against gsap 3.15.0 and svg-scroll-draw 2.10.0. Full comparison →
Import useScrollDraw from svg-scroll-draw/solid. It returns a callback ref you pass directly to ref={} on the element wrapping your SVG. The animation runs outside Solid’s reactive graph, so it triggers no re-renders.
No. The engine writes to the DOM directly rather than updating a signal each frame, so no reactive computation is invalidated by the animation. Only the elements being animated change.
Yes. Initialisation happens inside onMount, so nothing runs during server rendering, and onCleanup destroys the instance when the component unmounts.