What's new in 0.6.0.
The premium editor port lands in the open-source packages: multiple video tracks, clip speed, crop and corner radius, layered text animation with 14 templates, frame sequences, stored project documents with media re-linking - and the eight defects found while verifying it.
Multiple video tracks, clip speed, crop and corner radius
Stack video lanes, retime clips from 0.25× to 4×, and pin or protect tracks.
Read the docsLayered text motion and 14 templates
In and out motion with back, elastic, and bounce easings, applied as one template call.
Read the docsFrame sequences
Turn a numbered image set — a 360° orbit, a flipbook — into a scrubbable timeline clip.
Read the docsStored project documents and re-linking
Save a versioned project, load it back, and reconnect media that moved.
Read the docsTheming tokens
Restyle the editor and overlays with --elah-* tokens and per-slot classNames.
Read the docs@elah/react
The React bindings now ship as their own package: EditorContext, hooks, and the audio mixer.
Read the docsChoose a library.
Five composable packages. Drop in the whole editor, or take only the layer you need.
Built for precision.
Every layer of the stack is designed around one principle: determinism. Same input, same output, every time.
Frame-Accurate Time Model
All time is integer frames — no floating-point drift, no sync bugs. Same project + same frame = same pixels, always.
WebCodecs Decode Pipeline
Push-based StreamingFrameProducer with ahead-of-playhead decoding. Frames are copied to ImageBitmap so the hardware output pool never starves, and a shared sourceBlobCache keeps one copy of each video’s bytes.
WebGL2 GPU Renderer
GpuRenderer turns each resolved Scene into sorted textured-quad draws composited by zIndex. Layers: Video, Image, Text, Shape, and Freehand.
Pure Resolver Architecture
resolveTimeline(frame, project) → Scene is deterministic and side-effect-free. Runs identically in preview, tests, and export workers.
Zero-Drift Export — Browser & Server
The export worker steps resolveTimeline frame-by-frame in the browser — and @elah/cli runs the exact same pipeline headlessly on your server. outputHeight sets the short edge, so one value suits landscape and portrait.
Interactive Transform Overlays
Video and image clips get eight resize handles, non-uniform scale (Shift keeps aspect), and a Resize/Crop toggle. Text clips add inline edit and a rotate knob that snaps to 15°. Crop and corner radius are clip properties you set through the engine.
Edit History & Stored Projects
Every edit goes through TimelineEngine.commit() — Immer-backed structural sharing with batching, undo/redo, and typed events. Projects round-trip as versioned documents: readProjectDocument to load, relinkProjectMedia to reconnect files.
Transitions & Layered Motion
Fade, slide, and wipe transitions render the same in preview and export. Text and shapes take layered in/out motion with back, elastic, and bounce easings, plus 14 built-in text templates.
Multi-Track Editing
Stack multiple video tracks, retime clips from 0.25× to 4× with engine.setClipSpeed, and protect or pin tracks in place. Audio runs through a multi-track mixer with per-track levels and a master volume.
One mutation funnel.
One pure resolver.
Launch a playground.
Explore the editor live. Each playground is a fully functional deployment of the SDK.
Drop in. Wire. Ship.
The full editor composes in fewer than 20 lines. Bring your own demuxer factory and the preview handles decode, render, playback, and audio automatically.
Built to be driven by agents.
Integer-frame time, one mutation funnel, and a pure resolver make the engine easy for a model to reason about. Here is what you can use today.
One-file integration guide
ELAH_FOR_AI_AGENTS.md is a self-contained brief: the API surface and the gotchas, with no repo checkout needed.
Open the guideRender what the model writes
npx @elah/cli serve renders AI-generated specs to MP4 on your own hardware, frame-identical to the browser.
Openllms.txt for discovery
Every docs page is indexed in plain text at /llms.txt, so an agent can find the right page without scraping.
Open