Visual debugger for GSAP, CSS & WAAPI animations

See every animation on your site as a scrubbable timeline track.

Timeline Lens
0s0.5s1.0s1.5s2.0s2.5s
GSAP · tl › .hero-title
CSS · @keyframes › .card::before
GSAP · scrollTrigger › .cards
WAAPI · transition › .nav-link
Get the NPM package

What it’s all about

Your animations already exist: GSAP tweens, CSS keyframes, transitions, WAAPI calls. Timeline Lens just makes them visible, laid out as tracks you can scrub.

console.log() tells you a tween exists. Timeline Lens shows you where it starts, how long it runs, what it targets and how it eases, across GSAP, CSS and WAAPI alike, while the page keeps doing its thing.

Timelines ScrollTrigger matchMedia CSS animations Transitions element.animate() Scroll-driven view() React & Next.js

What it does

Four things, done properly.

01 / 04
Detect 1

Walks gsap.globalTimeline and polls document.getAnimations() to catch every GSAP tween, CSS animation, CSS transition and element.animate() call running on the page, including ones that already finished and got pruned.

Scrub 2

Play, pause, reverse, change speed, or drag the playhead across real GSAP and native WAAPI instances alike. Nothing here is faked: you are driving the actual animations.

Inspect 3

See each animation’s targets, timing, easing and keyframes, plus a best-effort reconstruction of the call that created it: a GSAP tween, a CSS rule, or a WAAPI animate().

Highlight 4

Hover any track and its real DOM target lights up on the page, so you always know exactly what is moving, whatever engine is driving it.

See it detect

One tool, three engines.

GSAP

Detected via gsap.globalTimeline

gsap.timeline({ repeat: -1, yoyo: true }) .to('.shape', { rotation: 180, scale: 1.2, borderRadius: '50%' }) .to('.shape', { rotation: 360, scale: 1, borderRadius: '16px' });
CSS

Detected via document.getAnimations()

/* plain @keyframes, no JS at all */ @keyframes pulse { 35% { transform: scale(1.15) rotate(90deg); } 70% { transform: scale(0.9) rotate(180deg); } }
Web Animations API

Detected via element.animate()

shape.animate([ { transform: 'translateY(0) rotate(0deg)' }, { transform: 'translateY(-16px) rotate(90deg)' }, { transform: 'translateY(0) rotate(180deg)' }, { transform: 'translateY(-10px) rotate(270deg)' }, { transform: 'translateY(0) rotate(360deg)' }, ], { duration: 2800, iterations: Infinity });

Available now

Start with the npm package. A browser extension is on the way.

npm package

Mount it behind a dev guard

Install timeline-lens as a dev dependency. It detects GSAP, CSS animations and transitions, element.animate() and WAAPI out of the box. GSAP is never a hard dependency: it resolves through a dynamic import that's allowed to fail, so the studio still runs fine on CSS and WAAPI alone when GSAP isn't installed.

For more information, see the documentation.

if (import.meta.env.DEV) { import('timeline-lens') .then((m) => m.init()); } // dev-only. Ships nothing to production.
Browser extension- coming soon

One click on any page

Same detection engines as the npm package (GSAP, CSS animations, transitions, element.animate() and WAAPI) on any page, whether or not it exposes window.gsap. Click the icon to mount the panel, click again to toggle it away. Currently in testing ahead of its launch.

https://that-award-winning-site.com
Coming soon Same detection engines as the npm package, for any page you visit
01

Install it

Add timeline-lens as a dev dependency: npm install --save-dev timeline-lens. It detects GSAP, CSS and WAAPI animations already in your project, no configuration needed. A browser extension for any page is on the way.

02

Guard it, then open it

Import it behind a dev-only check, such as import.meta.env.DEV in Vite or process.env.NODE_ENV in webpack and Next.js, then call init(). A floating trigger button mounts in a Shadow DOM root, so its styles never collide with your page.

03

Debug visually

Click the trigger, or call toggle() yourself. Every animation, whatever engine authored it, appears as a named, scrubbable track: play, pause, inspect, highlight, then close it and ship.