cookbookcanonicalOWNER-2026-07-10

Cookbook — GSAP + ScrollTrigger · cb-gsap

Owner directive (2026-07-10), canonical. "the pristine usage of the languages and technologies is not a request, is an order, just execute what is being said in official doc." [src: wiki/development/prompts-archive/by-topic/knowledge-management-and-concept-modeling.md:610]

Official docs

itempinreference
gsap (+ ScrollTrigger, SplitText, MorphSVG, DrawSVG, ScrollTo — free since 3.13)3.15.0 [src: HOS-Instance/packages/engine/package.json:18]https://gsap.com/docs

Our proven patterns

  1. Single registration module. One file registers GSAP + every scroll plugin the module library uses and re-exports them (import { gsap, ScrollTrigger, SplitText } from '@/lib/scroll/register'). Server components must NOT import it — plugins touch window. [src: HOS-Webdoc/web/src/lib/scroll/register.ts:1]
  2. Register-once guard. gsap.registerPlugin(...) behind a module-level boolean; also applied in the engine before creating any trigger. [src: HOS-Instance/packages/engine/src/engine/scroll.ts:40]
  3. ScrollTrigger.update() from the Lenis scroll event — keeps triggers in sync with the smoothed position (see cb-lenis). [src: HOS-Instance/packages/engine/src/engine/scroll.ts:72]
  4. DEFAULT_SCRUB = 1 — the standard scrub smoothing across pinned/scrubbed modules; do not scatter magic scrub values. [src: HOS-Webdoc/web/src/lib/scroll/types.ts:20]
  5. Reveals keep per-section triggers; the master progress does not. Page progress is emitted straight from scroll position; only local reveals own ScrollTriggers. [src: HOS-Instance/packages/engine/src/engine/scroll.ts:60]
  6. killAllScrollTriggers on route change — exported alongside the plugins so SPA navigation can tear down cleanly. [src: HOS-Webdoc/web/src/lib/scroll/register.ts:44]
  7. Slow, weighted brand motion: power3.out, 0.8–1.2 s beats is the HOS venture default (e.g. Royal Orbit genome motion.easing: "power3.out" [src: wiki/organizations/instances/royalorbit/genome.json:374]).

Gotchas

  • Observer/Flip TS1149 casing conflict. gsap ships capitalized JS but lowercase .d.ts for Observer/Flip; registering them breaks cross-platform builds once gsap's own index.d.ts is in the program. Implement infinite-scroll and page transitions with ScrollTrigger instead. [src: HOS-Webdoc/web/src/lib/scroll/register.ts:19]
  • An animation-less scrub trigger does not reliably fire onUpdate — never use one as a progress source (the Lenis-emit gotcha, see cb-lenis). [src: HOS-Instance/packages/engine/src/engine/scroll.ts:60]
  • gsap.ticker.lagSmoothing(0) when Lenis rides the ticker — lag smoothing otherwise desyncs scroll from render. [src: HOS-Instance/packages/engine/src/engine/scroll.ts:77]

Budgets

Animation work counts against the frame budget in bm-001-web-perf.

Composition

See also

Linked from — 11 cards