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.

BrowserCLICloud
Best forUser exports, local previewLocal dev, CIProduction, automated pipelines
Speed1–4× real-time1–4× real-time~1 min any length
InfrastructureNoneLocal ffmpegNone
CostFreeFree$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 cloud

Start in the browser.
Scale when you're ready.

Pick a target, write your composition, and ship it.