Turn any SVG animation into a real MP4
SMIL, CSS, JS-driven — every flavor of SVG animation, rendered to a deterministic MP4 you can ship anywhere.
SVG is the best animation format on the web that almost nobody uses as a source format for video. You can author once in SVG, render to MP4 for social, render to GIF for email, render to a PNG sequence for an editor. The asset is reproducible, version-controlled, and small.
Here is how to render the three main flavors of animated SVG — SMIL, CSS, and JS-driven — to a deterministic MP4.
The three kinds of SVG animation
Almost every animated SVG in the wild is one of these:
- SMIL — the legacy
<animate>and<animateTransform>tags. Native, no JS, declarative. - CSS-animated SVG — SVG elements with CSS
animationortransitionapplied. Standard web animation, applied to SVG. - JS-driven SVG — JS reads the clock and mutates SVG attributes per frame. Maximum control.
All three can be rendered to MP4. The trick is each one needs a slightly different bridge to make the renderer scrub deterministically.
Bridge 1: SMIL
SMIL animations run on their own internal clock. To make a SMIL SVG renderable, you need to expose a "seek to time" hook. The standard pattern:
<svg>
<circle r="20" cy="100">
<animate attributeName="cx" from="0" to="800" dur="4s" repeatCount="indefinite" />
</circle>
<script>
addEventListener('hf-seek', e => {
document.documentElement.setCurrentTime(e.detail.time);
});
</script>
</svg>setCurrentTime is the SVG-native way to scrub. The HyperFrames renderer dispatches hf-seek events; this two-line bridge wires them up.
Bridge 2: CSS-animated SVG
CSS animations on SVG elements have the same problem as CSS animations on HTML: they want to run on a wall clock you do not control. The fix is the same — pause the animation and set animation-delay to a negative value per frame.
addEventListener('hf-seek', e => {
document.querySelectorAll('[data-anim]').forEach(el => {
el.style.animationPlayState = 'paused';
el.style.animationDelay = `-${e.detail.time}s`;
});
});This works for any CSS animation, not just SVG. The negative delay scrubs the animation to the requested time and the paused state freezes it there.
Bridge 3: JS-driven SVG
JS-driven is the easiest because you already have a clock you control. Just call your render(t) function with the seek time:
function render(t) {
circle.setAttribute('cx', t * 200);
}
addEventListener('hf-seek', e => render(e.detail.time));
render(0);Pure function of time, no internal state. This is the same pattern we use for particle effects and data viz — and it is the only one of the three that gives byte-identical renders across machines.
Paste your own SVG
If you have an existing SVG animation, the conversion is usually:
- Find the animation driver (SMIL, CSS, JS).
- Add the appropriate bridge above.
- Test by scrubbing — does the SVG look right at t=0, t=2, t=4?
If scrubbing looks broken, it is almost always because the animation has internal state (a setInterval, an accumulator). Replace those with pure functions of t. See our DOM-to-MP4 walkthrough for the longer version of this story.
The render
Once the SVG scrubs cleanly, render it. Open the HyperFrames playground, paste the SVG (wrap it in <!doctype html><html><body>...), set duration, render. You get an MP4.
Why MP4 and not GIF
GIF is 256 colors, no audio, and 30-50× the file size of equivalent MP4. The only case for GIF is "the platform does not allow MP4" — usually email. For everything else, MP4 wins on quality and size. We covered the GIF-vs-MP4 tradeoff in detail if you want the numbers.
The reproducibility win
The reason this matters: an SVG you rendered to MP4 last quarter, with the same template and same data, renders to the same bytes today. That is not true of any timeline-tool export. Determinism is the feature that compounds — every render after the first is a build, not a craft. SVG-as-source is one of the cleanest ways to get there.
Cite this postBibTeX · APA · Markdown
@misc{park2026turn,
author = {Ren Park},
title = {Turn any SVG animation into a real MP4},
year = {2026},
url = {https://hyperframes.video/blog/svg-animation-to-mp4},
note = {HyperFrames blog}
}Ren Park. (2026, May 9). Turn any SVG animation into a real MP4. HyperFrames. https://hyperframes.video/blog/svg-animation-to-mp4
[Turn any SVG animation into a real MP4](https://hyperframes.video/blog/svg-animation-to-mp4) — Ren Park, 2026
Ren writes guides, runs workshops, and breaks the CLI on purpose so you do not have to. Previously dev rel at a CI company; before that, an actual filmmaker.
Animated flight itinerary cards in HTML
Build an animated boarding pass video: a plane traces an arc from origin to destination, gate and time settle in, the pass folds out — rendered as MP4.
Animated poll results as MP4
Build a poll results animation that renders to deterministic MP4: four horizontal bars race to their final percentages, then a winner ribbon sweeps in.
Animated fitness summary cards (Strava-style recaps)
Build a fitness recap video generator: distance, pace, and elevation tick up, a route map traces itself, and weekly streak dots fill in — exported as MP4.
Building with HyperFrames? Come hang out.
We're on GitHub, in Discord, and the playground is one click away. Bring weird ideas — we collect them.