Motion is a deterministic, agent-native video engine built on Next.js. A render request describes scenes, nodes, transforms, and animations as plain data. The server resolves each frame with a pure animation layer, rasterizes it through skia-canvas, and streams raw RGBA frames into ffmpeg to produce an MP4.
- Bun
- A local
ffmpegbinary available on yourPATH - macOS Metal support if you want the default
h264_videotoolboxhardware encoder
You can verify ffmpeg is installed with:
ffmpeg -versionbun install
bun run devFor the prompt-to-video flow, set:
AI_GATEWAY_API_KEY=your_key_herePOST /api/render
Example request body:
{
"width": 640,
"height": 360,
"fps": 12,
"background": "#07111f",
"scenes": [
{
"id": "intro",
"startFrame": 0,
"durationInFrames": 24,
"background": "#07111f",
"nodes": [
{
"id": "card",
"type": "rect",
"width": 544,
"height": 220,
"radius": 24,
"fill": "#0f172a",
"transform": {
"x": 48,
"y": 72
}
},
{
"id": "headline",
"type": "text",
"text": "Deterministic video",
"fontSize": 42,
"transform": {
"x": 88,
"y": 112
},
"animations": [
{
"type": "effect",
"name": "fade-in",
"startFrame": 0,
"endFrame": 10
}
]
}
]
}
]
}Example curl:
curl -X POST http://localhost:3000/api/render \
-H "Content-Type: application/json" \
-d @request.jsonSuccessful responses return a job id, output metadata, and a URL such as /renders/<job-id>.mp4.
A sample render request lives at lib/video/fixtures/sample-video-description.ts.
Render it locally:
bun run render:fixtureRun a live prompt generation plus render with the sample prompt:
bun run prompt:smokebun test
bun run typecheck
bun x ultracite check