Skip to content
Workflows that ship

Make a marketing video with Claude and HTML motion

Build the video as a web page with a deterministic timeline, render the frames, and let ffmpeg do the rest.

2 min read · prompt included

A short product video is just a page that animates on a clock you control. The VibeBox showreel (right) was made this way from the site's own components, tokens and 3D sculptures.

Recipe

  1. Storyboard in beats. Pick a tempo (128 BPM is 0.47s a beat) and write what happens each 4 or 8 beats: one idea per cut.
  2. One timeline. Drive every element from a single time value t (no real-time CSS animations), so frame 312 is always the same picture.
  3. Build scenes as components with your real fonts, tokens and screenshots; match-cut from a headline to the real page.
  4. Render. Step t by 1/60 s in headless Chromium (Playwright), screenshot each frame, and encode with ffmpeg (H.264, yuv420p, +faststart).
  5. Sound. Synthesise a simple loop on the same grid, or use licensed music; cut on the beat.
  6. Export 9:16 for Reels and Shorts, 4:5 for feeds, 16:9 for the site.

Keep text on screen for at least 1.5 seconds and never narrate what the picture already says. Fifteen seconds is plenty.

Prompt · Video from HTML
Build a 15-second 9:16 marketing video for [product] as an HTML page driven by one timeline function render(t).
Tempo 128 BPM; cuts land on beats. Storyboard: [0-2s logo reveal], [2-4s headline in kinetic type], [4-7s three real screenshots], [7-9s one stat], [9-11s price or offer], [11-15s end card with the URL].
Use these tokens: [colours], fonts [families]. Only animate transform and opacity; no CSS transitions, everything is computed from t.
Then write render.mjs: open the page in Playwright at 1080x1920, step t by 1/60, save frames, and encode with ffmpeg -c:v libx264 -pix_fmt yuv420p -movflags +faststart. Give me a --preview flag at 30fps and --stills 2.9,7.1,14.9 to check single frames.
The VibeBox showreel: 15 seconds, 9:16, an HTML timeline rendered with Playwright and ffmpeg.
↑ ↓ to move↵ to openesc to close