oxframe vs Revideo
Pick oxframe when you want templated videos rendered natively, with no browser and no telemetry, and an agent that checks its own frames. Pick Revideo when you want the Motion Canvas model in TypeScript with a React player and render endpoints out of the box.
At a glance
| oxframe | Revideo | |
|---|---|---|
| Language | Rust | TypeScript |
| Origin | Its own engine | A fork of Motion Canvas |
| Renderer | Native, CPU or GPU | Headless browser |
| Variables per render | Rust values and functions | useScene().variables and renderVideo variables |
| Parallel rendering | render --jobs N, the same bytes for any N | Parallelized rendering |
| Player for a web page | Playground and editor | React <Player/> |
| Telemetry | None | Counts rendered videos via PostHog; DISABLE_TELEMETRY=true turns it off |
| Releases | 0.20.4, October 2026 | No GitHub releases; 0.11.0 on npm |
| An agent sees the frames | oxframe check with a JSON report, MCP server | You wire that yourself |
| License | MIT or Apache-2.0 | MIT |
One scene in both
The scene from the Revideo migration guide: a welcome card with a name passed in at render time. Two seconds at 1080p.
Revideo
// src/scenes/card.tsx
import {Txt, makeScene2D} from '@revideo/2d';
import {createRef, useScene, waitFor} from '@revideo/core';
export default makeScene2D('card', function* (view) {
const name = useScene().variables.get('name', 'Ada');
const title = createRef<Txt>();
view.add(<Txt ref={title} text={`Welcome, ${name()}`} fontSize={96} fill={'white'} opacity={0} />);
yield* title().opacity(1, 0.5);
yield* waitFor(1.5);
});
// render.ts
import {renderVideo} from '@revideo/renderer';
await renderVideo({
projectFile: './src/project.ts',
variables: {name: 'Grace'},
settings: {outFile: 'welcome.mp4'},
});oxframe
use oxframe::prelude::*;
#[oxframe::scene]
pub async fn card(view: View) {
// Revideo's variables: here the environment (or a file you read).
let name = std::env::var("NAME").unwrap_or_else(|_| "Ada".into());
let title = view.add(Txt::new().text(format!("Welcome, {name}")).display().opacity(0.0));
title.opacity().to(1.0, 0.5).await;
wait_for(1.5).await;
}
pub fn project() -> Project {
Project::new("welcome").scene(card())
}Render time
| Tool | Command | Time |
|---|---|---|
| Revideo 0.11.0 | npx tsx render.ts (renderVideo) | 2.09 s |
| oxframe 0.20.4 | render --cpu | 0.69 s |
| oxframe 0.20.4 | render (GPU) | 2.15 s |
Each time is the whole render command, start to file. oxframe's scene is already compiled;
after a one-line edit, cargo build adds about 0.6 s. On a scene this short the
GPU spends more time starting than drawing, so the CPU renderer wins. The script is bench/vs/measure.sh: run it to time both on your machine.
Templated video without a browser
Revideo took Motion Canvas and made it a rendering engine: scenes read variables, renderVideo renders a project from Node, and a CLI exposes a render endpoint. Its README says it runs anywhere Node and a headless browser run, including serverless platforms, and that it is the engine behind Midrender. It also counts rendered videos anonymously through PostHog unless DISABLE_TELEMETRY=true is set.
oxframe covers the same job natively. A scene takes its data as Rust values, the CLI renders it in parallel segments, and the bytes do not depend on the machine or the number of jobs. Nothing is sent anywhere. The welcome card below is the same scene in both; the times are on this page.
What Revideo adds, in oxframe
Revideo's scenes are Motion Canvas scenes, and they port the same way: generators become async fn, yield* becomes .await. What Revideo adds on top maps like this:
| Revideo | oxframe |
|---|---|
useScene().variables.get('name', 'Ada') | ordinary Rust: read the value from the environment or a file, or build the project in main from it |
renderVideo({ projectFile, variables, settings }) | NAME=Grace oxframe render --out welcome.mp4; a loop renders one video per input |
| rendering in a headless browser | no browser: oxframe draws frames itself, on the GPU or with --cpu |
| parallel rendering | oxframe render --jobs 8: 2-second segments in parallel, the same bytes as one job |
<Audio>, <Video> | sound(…).play(), Audio::track(…), Video (feature video) |
| the React player | no published player package yet: share the video or a playground link |
One detail from porting the welcome card: in Revideo 0.11.0 a text given as a function, text={() => `Welcome, ${name()}`}, rendered an empty frame in our test, while the same text as a string rendered; the guide's code uses the string.
When to pick Revideo
- You want TypeScript and the Motion Canvas model with headless rendering.
- You embed a player in a React app and render from Node.
When to pick oxframe
- Renders should not need a browser and should be byte-identical.
- You want no telemetry, with nothing to turn off.
- An agent writes or fills the templates and should check the frames.
- You want regular releases and a changelog.
Moving from Revideo
The Revideo migration guide maps scenes, variables and renderVideo to oxframe and ports the welcome card above.
FAQ
Is Revideo still developed?
Its README describes it as the engine behind Midrender. It has no GitHub releases; npm has 0.11.0. Check its repository for the current state.
Does Revideo send telemetry?
Its README says it anonymously counts how many videos are rendered, via PostHog, and that DISABLE_TELEMETRY=true disables it. oxframe has no telemetry.
Can oxframe render a video per row of data?
Yes. A scene is a Rust function, so it takes any data you pass it; render one video per row from a loop or a script.
Is there a player for web pages?
Revideo has a React player. oxframe has the playground and the editor; a player to embed in your own page is not available yet.
How hard is it to move from Revideo?
Revideo scenes are Motion Canvas scenes, which map almost line by line: generators become async functions and yield* becomes .await. The migration guide shows one.
Sources
Checked on October 22, 2026. Found something out of date? Open an issue on oxframe-web.
- Revideo on GitHub
- @revideo/core on npm
- oxframe license and what leaves your machine
- oxframe-sdk on GitHub