We're dsplce.co, check out our work on our website: dsplce.co 🖤
⚡ 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.
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 channel- Frame-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
⸻
Install from crates.io using cargo:
cargo install htmlrecAfter installation, the hrec command will be available in your terminal.
⸻
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.
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.
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 |
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"| 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⸻
- Chromium or Chrome: A working Chromium/Chrome installation accessible to the system —
htmlreclaunches it headlessly to capture frames - ffmpeg: Used to encode the captured PNG frames into the output video — must be available on your
PATH - cargo: For installation from source
⸻
🛠️ Repo: https://github.com/dsplce-co/htmlrec
📦 Crate: https://crates.io/crates/htmlrec
PRs welcome, feel free to contribute
⸻
MIT or Apache-2.0, at your option.