Visual inspector 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

What it’s all about

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

Timeline Lens shows you where animations start, how long they run, what they target and how they ease, across GSAP, CSS and WAAPI alike, while the page keeps doing its thing.

Timelines ScrollTrigger matchMedia CSS animations Transitions element.animate() Scroll-driven view() Astro React Next.js JavaScript or TypeScript

See it for yourself

Try it now. This page is already running Timeline Lens.

Every GSAP tween, CSS animation and WAAPI call you've scrolled past so far is already being tracked. Open the live panel to scrub through them for real, on this exact page; no install required.

01

Click “Launch the live demo” below and an icon will appear in the bottom-right corner of the page.

02

Every animation on this page appears instantly as a named, scrubbable track - the same panel the npm package and browser extension both use.

03

Drag the playhead, hover a track to highlight its target on the page, then close it and keep browsing.

What it does

Four things, done properly.

01 / 04
Detect 1

Walks your JavaScript or Typescript files 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 });

Why reach for it

Built for the debugging sessions you actually have.

ScrollTrigger

A pinned section stutters, but only in production

Symptom

Your ScrollTrigger-pinned hero scrubs smoothly on localhost, but jitters once real images and content load in.

With Timeline Lens

Scrub to the exact scroll offset where it breaks, inspect the pin's start, end and easing, and see whether it's your tween or a layout shift fighting it.

CSS transition

A hover transition looks like it's firing twice

Symptom

A nav link or button's transition seems to restart itself, or snap back before it finishes.

With Timeline Lens

Open the track for that element, scrub through its start and end state frame by frame, and read the real timing and easing without clicking through DevTools' Animations panel one class at a time.

Third-party page

Something on someone else's site is animating oddly

Symptom

You're looking at a competitor's site or a client's staging build and want to know what's actually driving an effect, with no access to the source.

With Timeline Lens

Install the extension, click the icon, and every GSAP tween, CSS animation and WAAPI call on the page shows up as a scrubbable track, whether or not the page exposes window.gsap.

Available now

NPM package for local development, or a browser extension for any page.

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 Timeline Lens 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

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.

Free to install on the Chrome Web Store, with an optional $9.99 Pro upgrade to unlock all the features. The Pro upgrade is a one-time payment, not a subscription, and it helps support development of Timeline Lens.

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

Install it locally

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 (see docs). Every animation, whatever engine authored it, appears as a named, scrubbable track: play, pause, inspect, highlight, then close it and ship.