elah

Introduction

elah is an open, framework-agnostic architecture for building browser-native video editors. It currently ships first-class support for Next.js and React, with React Native (experimental) and more frameworks coming soon. Engine-first, renderer-agnostic, scalable from MVP to production.

elah is not a drag-and-drop video editing app you open in a browser. It is the engine, resolver, and timeline SDK that any modern web-based video editor should sit on.

Three goals shape every decision:

  1. 1.
    Deterministic playback
    Same project + same frame = same pixels, always. Time is integer frames; never floating-point seconds.
  2. 2.
    Renderer-agnostic core
    The data model and timeline resolver know nothing about DOM, Canvas, WebGL, or WebGPU. Swap rendering backends without touching state.
  3. 3.
    Iteration speed
    Small surface area, no plugin systems, no over-engineered abstractions. You can read the entire core in one sitting.

Architecture

A single immutable Project tree owns all timeline data. The framework-agnostic TimelineEngine is the only place mutations happen — every edit is an Immer-backed commit with structural sharing, history, batching, and typed events.

A pure function resolveTimeline(frame, project) → Scene determines what is visible and audible at any frame. This is the only thing renderers consume — the shipped renderer is a WebGL2 GpuRenderer that turns each Scene into sorted textured-quad draws.

React UI Layer
TimelinePreviewAssetPanelTransform OverlaysTransitionOverlay
Zustand Stores
useTracksStoreusePlaybackStoreuseSelectionStoreuseTransitionsStore
Engine Layer
TimelineEnginePlaybackEngineAudioPlaybackController
Pure Resolver
resolveTimeline(frame, project) → Scene
Renderer Interface
GpuRenderer (WebGL2)ExportWorker (OffscreenCanvas)
Media Pipeline
StreamingFrameProducerWebCodecs APImediabunny demuxImageBitmap cache

Packages

@elah/editor
The full SDK. Exports EditorProvider, Timeline, Preview, AssetPanel, all hooks, and re-exports core.
@elah/core
Framework-agnostic engine. TimelineEngine, PlaybackEngine, resolveTimeline, GpuRenderer, export pipeline. Zero React imports.
@elah/timeline
React timeline UI components. Timeline, Ruler, TrackRow, ClipBlock, Playhead, and all interaction hooks.

Design Principles

Engine-first. The core is plain TypeScript. React is a consumer, not a master.
Frames, not seconds. Integer time eliminates a class of floating-point bugs that haunt every NLE.
One mutation funnel. All edits go through TimelineEngine.commit(). No back-doors.
Pure resolver. resolveTimeline is deterministic and side-effect-free — runs in tests, workers, and export pipelines without ceremony.
Renderer is just a consumer. A renderer reads Scene, writes pixels, and knows nothing else.
Small surface area. No plugin systems, no event buses, no dependency injection — until proven needed.

Next Steps