editframe/render
Write once.
Render anywhere.
HTML and CSS compositions that render in the browser, via CLI, or in the cloud. No video engineering required. If you can build a webpage, you can build video.
| Browser | CLI | Cloud | |
|---|---|---|---|
| Best for | User exports, local preview | Local dev, CI | Production, automated pipelines |
| Speed | 1–4× real-time | 1–4× real-time | ~1 min any length |
| Infrastructure | None | Local ffmpeg | None |
| Cost | Free | Free | $0.02 / min |
| API key needed | |||
| Scales to 1,000/day |
The same composition file works across all three. Develop free in the browser, test via CLI, switch to cloud with one config change when you're ready to scale. The editframe CLI covers both: render locally for free, or trigger a cloud job with cloud-render.
Want your users to export video themselves, entirely client-side? See the SDK.
Full browser rendering
If it runs in a browser,
it renders to video.
Full CSS. Real DOM. If it runs in a browser, it renders to video: animations, transforms, custom fonts, the whole platform.
Full CSS
Animations, transitions, filters, transforms, custom fonts, clip-path, backdrop-filter. All of it, exactly as the browser renders it.
Canvas & WebGL
Three.js, React Three Fiber, raw Canvas 2D, PIXI.js, Lottie, Rive. Drop them into a composition and they render to MP4, frame by frame.
SVG & DOM
Animated SVG, data visualizations, charts. Anything that lives in the DOM renders correctly, no special handling needed.
CSS animation, position: sticky, backdrop-filter, scroll-driven effects, custom fonts. These only work when a real browser is painting the frame. Editframe renders in a full Chromium instance. If it works in a tab, it works in your video.
React support
Already in React?
Build your composition there too.
Pass your composition to TimelineRoot and drive it with React hooks like useTimingInfo. The same component renders in browser, CLI, and cloud unchanged.
Hooks give you playback time, media state, and pan/zoom. Everything your UI needs to stay in sync with the composition.
React composition docs →import { Timegroup, useTimingInfo }
from '@editframe/react'
const Scene = () => {
const { ref, percentComplete } = useTimingInfo()
return (
<Timegroup ref={ref} mode="fixed" duration="5s">
<div style={{ opacity: percentComplete }}>
Fading in...
</div>
</Timegroup>
)
}
// main.tsx
<TimelineRoot id="root" component={Scene} />
// Same component renders in browser, CLI, and cloudStart in the browser.
Scale when you're ready.
Pick a target, write your composition, and ship it.