Web
The five web modules: zero-dependency CSS, GSAP, Framer Motion, Three.js with React Three Fiber, and generative Canvas 2D.
All documentation
Selected from what your package.json already contains. If a library is there,
its module loads and that choice is respected. If nothing is there, the
zero-dependency module loads, and a dependency is proposed only when the thesis
genuinely needs one.
css-native
The default when no animation library is present, and often the right answer even when one is.
It covers scroll-driven animation through animation-timeline, both scroll
progress (scroll()) and view progress (view()) with animation-range and its
named ranges. The View Transitions API in both flavours: same-document for SPAs,
and cross-document for multi-page sites through @view-transition, including
view-transition-name for shared elements and view-transition-class for
styling a whole group.
Then @starting-style paired with transition-behavior: allow-discrete, which is
what makes entrance animation from display: none work without JavaScript timing
hacks. Anchor positioning for tooltips and popovers, with position-try-fallbacks
treated as mandatory rather than optional. Container queries driving different
animations at different component sizes. And the visual techniques: clip-path
reveals and shape morphing, backdrop-filter, mix-blend-mode, mesh gradients
approximated from layered radial gradients, and conic-gradient masking.
It carries a decision table for when to stop. Fewer than three animations, a
scroll reveal, an enter or exit from display: none, a tooltip, a page
transition: stay in CSS. A five-plus-step timeline, a stagger across a list of
unknown length, an interruptible physics spring, an SVG shape morph: that is when
a library earns its bytes.
Scroll-driven animation always ships behind @supports (animation-timeline: scroll()), and scroll-driven keyframes use animation-fill-mode: both, never
forwards, which would lock the element in its end state on the way back up.
gsap
Loads when GSAP is already a dependency. Core, timelines, ScrollTrigger and the plugin set, plus the critical mistakes worth naming out loud.
Never proposed as a replacement for an existing library.
framer-motion
Loads when Motion for React is already a dependency. AnimatePresence and exit
animation, layout animations, variant propagation and orchestration, gestures,
and motion values for animating without triggering re-renders.
Also carries the comparison against the alternatives, so the answer to “should this be Framer Motion or CSS” is reasoned rather than habitual.
threejs-r3f
Three.js and React Three Fiber. Scene setup patterns, the R3F hook set, the essential Drei helpers, postprocessing, and the performance patterns that decide whether 3D on the web is viable or a frame-rate disaster.
canvas-generative
Algorithmic and generative art in Canvas 2D, and the module behind every mark on this site.
DPR-aware sizing so a canvas is sharp on a retina display, resize handling that re-renders rather than stretching, and delta-capped rAF loops. Noise selection: Perlin for terrain and clouds, simplex for flow fields and organic motion, Worley for cell and caustic patterns, with fractional Brownian motion for detail and seeding for reproducibility. Particle systems built on a pre-allocated pool with swap-and-shrink recycling, so nothing is allocated at runtime. Flow fields as a grid of noise-derived angles that steer particles. L-systems as string rewriting plus turtle graphics. Double buffering for trail effects.
Four prohibitions that decide whether a canvas piece is smooth or not: never
clearRect when you want trails (fill translucently instead), never
getImageData inside the loop because it stalls on a GPU readback, never skip DPR
scaling, and never allocate inside update or render.