MotionForge
A Rust motion-graphics engine — declarative JSON in, rendered video out.
Role · Solo — pipeline, renderer, CLI
Renderer
Vello / wgpu
Authoring
Declarative JSON
Output
PNG · MP4 · WebM · MOV
Demo
Title intro: keyframes, easing, masked reveals
Audio visualiser driven by a muxed audio track
Taffy-backed flex layout animating in place
MotionForge turns a declarative JSON document into rendered motion graphics. There is no timeline UI and no node editor — the document is the source of truth, which makes compositions diffable, reviewable, and generatable by a program or an agent.
The project began with a deliberate core reset, and that reset is still the design discipline: a feature lands only when it fits cleanly into the staged pipeline. Nothing gets bolted on sideways.
The pipeline
JSON document
-> mf-parser read source-shaped JSON into raw schema data
-> mf-compiler validate, normalize, expand generators, resolve references,
build the dependency graph, prepare typed property sources
-> mf-eval compute one concrete frame from frame-native context
-> mf-layout Taffy-backed block/flex plus absolute positioning
-> mf-transform anchor, position, scale, rotation, skew, perspective
-> mf-resolver convert to renderer-ready scene data
-> mf-render-vello
-> PNG / frame sequence / MP4 / transparent WebM + MOV
Each stage has a contract, and the contracts are the point. The renderer consumes resolved scene data only — it cannot reach back for the document, which is what keeps it swappable. Evaluation is frame-native, so any frame can be computed independently without simulating the ones before it.
What it renders today
- Variables, layers, children, and style/transform/property namespaces.
- Frame-native context:
$frame,$time,$fps,$duration,$progress. - References, numeric expressions, keyframes, easing, and dependency-cycle detection.
- Vector nodes —
rect,ellipse,line,polygon,star,path— plus.svgimport that expands into native vector paths, so imported artwork animates and takes effects like anything else. groupnodes with hierarchy, clipping, opacity, grouped effects, and blend modes.- Text, image, video, and shader render providers. Video supports constant-rate
playback_rateand an animatabletime_remapcurve for speed ramps, freeze frames, and reverse. audiotimeline nodes with trim, volume, and pan, muxed into MP4.- Reusable
prefabdefinitions with child time scopes and time remapping. - Vector masks — clip and alpha mattes — with invert, feathering, and reveal presets.
- Scene
transitionnodes: fade, slide, wipe, iris, radial, and zoom. - Linear, radial, and conic gradient paints.
Assets resolve from local paths, http(s), or data: URIs — images, video, audio,
fonts, and .cube LUTs — fetched and decoded once, then cached. Remote fetching goes
through an injectable AssetFetcher so the library has no opinion about networking.