Updated 15 November 2026
To convert HTML to MP4, put the page in a HyperFrames project and run npx hyperframes render --output video.mp4. HyperFrames is free and open source under Apache 2.0, and rendering on your own computer needs no account. This guide builds a small animated page, renders it, and covers 60 fps, 4K, transparent video and GIF. Unlike screen-recording the page with Playwright or Puppeteer, HyperFrames seeks every frame to its exact time, so the video never drops or doubles frames.
Short answer: mark the page's root element with an ID, a size and a length, create its GSAP timeline paused, register it, and run one render command. Rather not touch code? Drop the HTML file into the free HyperFrames Studio app and ask for an MP4.
What does HyperFrames do with your HTML page?
The renderer never plays your page in real time. For each frame of the video it moves every animation to that frame's exact time, captures the picture in headless Chrome, then asks for the next one. FFmpeg encodes the pictures into the MP4.
A slow frame takes longer to capture, but it is never skipped, so a 4K render with heavy effects plays as smoothly as a plain one. GSAP is the default animation library. CSS keyframes, the Web Animations API, Lottie, Three.js and Anime.js are seeked the same way.
Starting from a Lottie file or an animated SVG? Each has its own guide: Lottie to MP4 and SVG to MP4.
What do you need before you start?
- Node.js 22 or newer.
- FFmpeg, which encodes the video. Run
npx hyperframes doctorto check both; it lists anything missing. - A terminal. No terminal? The Studio app route further down needs no code.
How do you convert HTML to MP4, step by step?
Step 1: Create a project
npx hyperframes init my-video --non-interactiveYou get a my-video folder with index.html, hyperframes.json, package.json and meta.json, plus AGENTS.md and CLAUDE.md, which explain the project to a coding agent. The command also installs the skills for your coding agent; add --skip-skills to leave them out.
Step 2: Write the page
Replace index.html with the page below. It is ordinary HTML, CSS and GSAP, plus three details the renderer reads:
- The root element carries
data-composition-id,data-width,data-heightanddata-duration, the length of the video. - Each element on screen has
class="clip"with its own start, duration and track. - The GSAP timeline is created with
paused: trueand registered onwindow.__timelinesunder the composition ID,main.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<style>
html, body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: #0f1115; }
#root { position: relative; width: 100%; height: 100%; font-family: Helvetica, Arial, sans-serif; color: #fff; }
#title { position: absolute; left: 160px; top: 380px; margin: 0; font-size: 120px; }
#bar { position: absolute; left: 160px; top: 560px; width: 900px; height: 16px; background: #4fdb5e; transform-origin: left center; }
#sub { position: absolute; left: 160px; top: 620px; margin: 0; font-size: 48px; color: #b8bcc6; }
</style>
</head>
<body>
<div id="root" data-composition-id="main" data-start="0" data-duration="5" data-width="1920" data-height="1080">
<h1 id="title" class="clip" data-start="0" data-duration="5" data-track-index="0">Hello from HTML</h1>
<div id="bar" class="clip" data-start="0" data-duration="5" data-track-index="1"></div>
<p id="sub" class="clip" data-start="0" data-duration="5" data-track-index="2">Rendered to MP4, frame by frame</p>
</div>
<script>
const tl = gsap.timeline({ paused: true });
tl.fromTo("#title", { opacity: 0, y: 60 }, { opacity: 1, y: 0, duration: 0.8, ease: "power3.out" }, 0);
tl.fromTo("#bar", { scaleX: 0 }, { scaleX: 1, duration: 1, ease: "power2.inOut" }, 0.4);
tl.fromTo("#sub", { opacity: 0, x: -40 }, { opacity: 1, x: 0, duration: 0.6 }, 1.2);
window.__timelines = window.__timelines || {};
window.__timelines["main"] = tl;
</script>
</body>
</html>The page never calls play(). The renderer owns the playhead and seeks the timeline to each frame. The title rises in, the green bar grows from the left, and the subtitle slides in at 1.2 seconds.
Step 3: Check it
cd my-video
npx hyperframes lint
npx hyperframes checklint reads the file and names any missing attribute. check loads the page in a browser and tests layout, motion, contrast and runtime errors. On this page it ends with Check passed and one craft warning: frame 0 shows only the background. Social players use the first frame as the thumbnail, so in a real video, put the title on screen at 0 seconds.
To watch it before rendering, run npx hyperframes preview. It opens the browser editor on port 3002, with a timeline you can scrub.
Step 4: Render the MP4
npx hyperframes render --output video.mp4The CLI captures 150 frames, 5 seconds at the default 30 fps, and writes video.mp4 at 1920 by 1080, the size the page declares. Leave out --output and the file lands in renders/, named after the project with the date and time.
Above: the render on screen. A project folder, the render command and its progress, the finished MP4 playing, then the flags that change the output.
Above: a film from the HyperFrames team's launch posts, made with HyperFrames.
How do you convert HTML to MP4 with your AI agent?
Claude Code, Codex and Cursor can run all four steps for you once the skills are installed. In Claude Code, install the plugin:
claude plugin marketplace add heygen-com/hyperframes
claude plugin install hyperframes@hyperframesFor Codex, Cursor and other agents, install the skills from a terminal, then start a new agent session:
npx hyperframes skills updateThen point the agent at your page and say what the video should do:
Using /hyperframes, turn landing.html into a 10-second 1080p video. Keep my layout and colours, animate the headline and the button, then render an MP4.The skills have the agent run check after its last edit, open the preview for you, and render once you approve it or ask for the file. You stay the director: reply to its plan, ask for changes, then say render.
How do you convert HTML to MP4 without writing code?
Use the HyperFrames Studio app, free for Mac, Windows and Linux with a free HeyGen account. It runs an AI agent beside a live preview, so you work by typing and pointing at the picture.
- Download the app, open it and sign in.
- Drop your HTML file, or the folder that holds it and its images, onto Make something. Each file waits in the box as a pill.
- Say what you want, for example "turn this page into a 10-second video and animate the headline", and send. The first time, Connect an agent asks which agent to use: the built-in HyperFrames agent, which needs no install and runs on your HyperFrames credits, or Claude Code, Codex, Grok, Antigravity, GitHub Copilot, Hermes Agent, OpenClaw, Qoder, or OpenCode, which runs free models.
- Watch the preview, ask for changes in the chat, then choose Export in the top bar and Render 1080p MP4.
Exports rendered on your computer are free, and the file lands in your Downloads folder. The free plan also includes 5 cloud exports a month; Pro, at $25 a month, makes them unlimited. The export guide lists every setting.
Which render options can you change?
Add these flags to npx hyperframes render. The page itself stays the same.
You want | Add | What to know |
|---|---|---|
60 fps |
| Any rate from 1 to 240, or 30000/1001 for 29.97 |
4K from a 1080p page |
| Text, SVG and CSS are redrawn sharp at 3840 by 2160; the aspect ratio must match |
Transparent web overlay |
| VP9 with alpha; leave html and body without a background |
Transparent file for editors |
| ProRes 4444 with alpha, for Premiere, Final Cut, Resolve and After Effects |
GIF |
| No sound, and GIF frame rates above 30 are capped at 30 |
PNG frames |
| One RGBA image per frame, for compositing tools |
A quick test render |
| Use the default quality for the final file |
The same file on every machine |
| Renders inside Docker |
Every flag is listed in the CLI reference, and the 4K guide covers sharp sources.
Why not screen-record the page or use an online converter?
A screen recorder captures what the browser draws while it plays, so any frame the computer draws too slowly is missing from the video. HyperFrames asks for each frame by number and waits until it is ready.
- Every frame, at any size. 4K at 60 fps comes out as smooth as 1080p, because no frame is skipped.
- The same frames on every run. Frame 90 depends only on the number 90, so agents and CI can re-render safely.
- Your files stay on your computer. A local render uploads nothing.
- A video you can keep editing. Change a word in the HTML and render again.
What goes wrong, and how do you fix it?
- Nothing moves, or lint reports
missing_timeline_registry. Create the GSAP timeline withpaused: trueand add it towindow.__timelinesunder thedata-composition-idvalue. - Every render waits about 45 seconds before it starts. The page has no GSAP timeline, so the renderer waits for one until it times out. Add
data-no-timelineto the root element. - Frames change between renders.
Math.random()andDate.now()give new values every run, and lint flags them asnon_deterministic_code. Seed the randomness or compute the values once. - A CSS animation jumps back to its first pose at the end. Add
animation-fill-mode: bothand a finite iteration count, so it holds its last frame. - The transparent WebM shows a black background. A background on
html,bodyor a full-frame element is encoded as pixels: remove it. Some players also draw black behind alpha, so check the file over a contrasting colour. --resolution 4kfails. The preset must match the page's shape: usesquare-4kfor a square page andportrait-4kfor a vertical one.- The render times out. The error names the budget that ran out. Raise
--browser-timeout(seconds) for a page that loads slowly, or--protocol-timeout(milliseconds) for one slow frame.
Related guides: AI motion graphics, the HyperFrames MCP server, the best free AI video editor, kinetic typography.
Questions people ask
Which HTML or browser features are supported?
HyperFrames renders in Chrome, so HTML, CSS, SVG, canvas and WebGL work. Animation must be seekable: HyperFrames drives GSAP, CSS animations, Web Animations, Anime.js, Lottie, Three.js and TypeGPU frame by frame. Avoid Date.now(), unseeded Math.random() and requestAnimationFrame loops, which change between renders.
How do fonts, media and audio resolve?
Keep them inside the project. Declare fonts with @font-face pointing at a file in the project, or use a Google Fonts family; an undeclared font falls back and lint reports it. Local media files are safest, because remote media can fail on permissions, expiring links or cross-origin rules.
How do I debug an incomplete or failed render?
Keep the full error, then run npx hyperframes lint and npx hyperframes check, and npx hyperframes doctor for the machine. If the render differs from the preview, check fonts and remote media, or render with --docker for a pinned environment.
Is there a free HTML to MP4 converter?
Yes. HyperFrames converts HTML to MP4 for free. It is open source under Apache 2.0, and rendering on your own computer needs no account. The HyperFrames Studio app is free too: it renders on your computer for free, with no watermark, and its free plan adds 5 cloud exports a month.
Can I convert a GSAP animation to MP4?
Yes. Create the GSAP timeline with paused: true, register it on window.__timelines under the composition ID, and run npx hyperframes render. HyperFrames seeks the timeline to every frame instead of playing it.
How do I convert a CSS animation to video?
Keep your CSS. HyperFrames finds CSS keyframe animations on its own and sets each one to the frame's time. Give each a finite iteration count and animation-fill-mode: both, put data-duration and data-no-timeline on the root, and render.
Can I render HTML to a transparent video?
Yes. Render with --format webm for a transparent web overlay, or --format mov for ProRes 4444 with alpha, which video editors read. Leave the page background unpainted wherever you want transparency.
Can I add music or a voiceover?
Yes. Put <audio> or <video> elements in the page with HyperFrames timing attributes, and FFmpeg mixes their sound into the MP4. Don't call play() from your script: HyperFrames plays media on the timeline.
Does it work on Windows, Mac and Linux?
Yes. The HyperFrames CLI runs wherever Node.js 22 and FFmpeg run, and the HyperFrames Studio app is available for Mac, Windows and Linux.
Can my AI agent convert the page for me?
Yes. Install the HyperFrames plugin in Claude Code, or run npx hyperframes skills update for Codex, Cursor and other agents, then ask for the video. The agent adds the attributes, checks the page and renders the MP4. It runs on your own agent plan, and OpenCode runs free models.

