htmlrec
⚡ Render HTML animations to video — frame-perfect, headless and deterministic.
htmlrec (hrec) is a command-line tool that captures HTML/CSS/JS animations into video files by driving a virtual clock through a headless Chromium instance, frame by frame.
🖤 Features
hrec render anim.html -o out.mp4Got a CSS or JS animation? Capture it to a crisp MP4, no screen recording neededhrec render anim.html -o out.webm --transparentNeed transparency? Export to WebM/VP9 or ProRes 4444 with a proper alpha channelFrame-perfect rendering — a virtual clock overrides
performance.now,Date.now,rAF,setTimeout,setInterval, and CSS animations so every frame is deterministic--zoomsupport for scaling elements before capture
Table of Contents
⸻
📦 Installation
cargo
Install from crates.io using cargo:
cargo install htmlrecAfter installation, the hrec command will be available in your terminal.
⸻
🧪 Usage
Render an animation to video
Point hrec at any HTML file containing a CSS or JS animation and it will render it frame by frame into a video:
hrec render animation.htmlBy default this produces output.mp4 at 1280×720, 30 fps, for 5 seconds.
All time-based browser APIs — performance.now, Date.now, requestAnimationFrame, setTimeout, setInterval, and CSS animations — are overridden by a virtual clock driven by hrec. This guarantees that every frame is captured at the exact right moment, regardless of how fast or slow the machine is.
Render with transparency
Export to WebM (VP9) or MOV (ProRes 4444) to preserve the alpha channel:
hrec render animation.html -o out.webm --transparent
hrec render animation.html -o out.mov --transparentThe --transparent flag omits the browser background and captures raw RGBA pixels per frame. Output must use .webm or .mov — using --transparent with .mp4 is an error.
Custom resolution and duration
hrec render animation.html -o out.mp4 --width 1920 --height 1080 --duration 10 --fps 60| Flag | Default | Description |
|---|---|---|
-o, --output | output.mp4 | Output video file |
-d, --duration | 5.0 | Duration in seconds |
-f, --fps | 30 | Frames per second |
--width | 1280 | Viewport width in pixels |
--height | 720 | Viewport height in pixels |
Zoom into an element
Scale any element before capture using CSS zoom:
# Zoom the root element to 2× (default target is :root)
hrec render animation.html -o out.mp4 --zoom 2.0
# Zoom a specific element
hrec render animation.html -o out.mp4 --zoom 0.5 --zoom-element ".card"Supported output formats
| Extension | Codec | Alpha |
|---|---|---|
.mp4 | H.264 / yuv420p | No |
.webm | VP9 / yuva420p | Yes |
.mov | ProRes 4444 / yuva444p10le | Yes |
Example HTML file:
animation.html:
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; background: #000; }
.box {
width: 100px; height: 100px;
background: #fff;
animation: slide 2s linear infinite;
}
@keyframes slide {
from { transform: translateX(0); }
to { transform: translateX(500px); }
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>hrec render animation.html -o out.mp4 --duration 2⸻
🛠️ Requirements
Chromium or Chrome: A working Chromium/Chrome installation accessible to the system —
htmlreclaunches it headlessly to capture framesffmpeg: Used to encode the captured PNG frames into the output video — must be available on your
PATHcargo: For installation from source
⸻
📁 Repo & Contributions
🛠️ Repo: https://github.com/dsplce-co/htmlrec 📦 Crate: https://crates.io/crates/htmlrec
PRs welcome, feel free to contribute
⸻
📄 Licence
MIT or Apache-2.0, at your option.