English | 한국어
A free, local, no-login video editor built with Electron, React, and a separate declarative TypeScript media engine.
Import local media → edit a timeline → preview the scene → export MP4 locally. The public source shows three engineering paths:
- Editor state: typed intents, immutable manifests, patch reconciliation, and undo/redo. Mutation pipeline · Contract tests
- Rendering: layer-ID lookup, ordered runtime layers, and recovery from reconciliation errors. Reconciler · Recovery/order tests
- Media output: WebCodecs encoding, MP4 muxing, and chunk writes across Electron IPC. Export pipeline · File handling
This is a source-stage project, with workspace packages at 0.1.0. As of October 2, 2026, there are no GitHub Releases or installer artifacts in those releases. The engine is available as public workspace source; its package configuration alone does not establish an npm release or a stable SDK contract.
The core editing and media-output path is local. AI chat and quick-prompt entry points are disabled in the public OSS workflow; retained parsers, provider files, tests, and historical AI designs do not make that feature available. See the OSS UI gate and scope decisions. Reconnecting an optional provider would require explaining which messages, editor context, and submitted images leave the device.
The release scope defines an import → edit → preview → export acceptance checklist. It is a plan, not a completed device acceptance report. Timeline UX remains an iteration area (TODO §4.10); professional NLE parity and broad codec compatibility are outside that release scope.
For an existing layer image-1 whose appearance.opacity is 1, a committed opacity edit can use this engine entry point:
import { engineStore } from '@rendium/engine';
engineStore.dispatchIntent({
type: 'CHANGE_OPACITY',
layerId: 'image-1',
opacity: 0.5,
});EngineIntentdefines the payload;dispatchIntentvalidates it before routing.IntentRouterchangeslayers['image-1'].appearance.opacityin an Immer recipe.EngineStorecreates the next manifest plus forward/inverse patches, records history, and forwards the patches to the scene.- The corresponding patch is shaped as
{ op: 'replace', path: ['layers', 'image-1', 'appearance', 'opacity'], value: 0.5 }.SceneReconcilerresolves the runtime layer by ID and appliesupdateConfig({ opacity: 0.5 }). - React consumes engine snapshots through
useSyncExternalStore. Undo/redo use the recorded patches; engine tests specify persisted edits, grouped edits, and transient-preview behavior.
This illustrates the public contract, not a standalone runnable project: the layer must exist first. During a drag or slider preview, dispatchTransient updates runtime state without adding manifest history; the committed intent creates the undo step.
For a timeline containing visual media and an audio layer, useExport passes the scene and selected export profile to WebCodecsPipeline:
prepareExport()crosses the preload bridge. The main process opens a save dialog, creates the chosen local file, and returns an export ID.- The pipeline requests a WebGPU device, renders frames, and passes them to
VideoEncoder. When audio layers exist, it also usesAudioEncoder. Encoded video/audio chunks go intomp4-muxer. - The muxer's chunked
StreamTargetcallswriteExportChunk(exportId, buffer, position). Electron main writes each chunk to the file handle at the supplied offset. - Finalization flushes the encoders, finalizes MP4 metadata, and requests file sync/close through IPC. The selected path is the output destination.
The chunked design sends muxed output incrementally instead of assembling one complete MP4 buffer in the renderer. It does not establish a memory ceiling, guaranteed hardware acceleration, or 60fps during export. The pipeline requests prefer-hardware; codec, GPU, and device support still matter. useExport tests mock the pipeline and are not end-to-end encoder/file acceptance evidence.
| Decision | Why it exists | Boundary or cost |
|---|---|---|
| Typed intents write the manifest; the scene reflects patches. | Keeps editor commands separate from runtime objects and gives persisted edits forward/inverse history. | Runtime and manifest must stay synchronized; recovery can rebuild the scene. Store · Recovery tests |
| Transient previews are separate from committed edits. | Avoids creating an undo entry for every pointer movement. | The UI must commit the final change explicitly. Preview/commit fixture |
| Layers have an ID registry and a separate ordered array. | Property patches address a layer directly; order changes can reuse runtime instances. | The narrow O(1) claim concerns layer-ID registry access. Reconciliation loops over patches, and reordering rebuilds an array; reconciliation as a whole is not O(1). Scene · Reconciler |
The CI configuration selects Node.js 20 and pnpm 10.33.0; the root package pins pnpm 10.33.0. From the workspace root:
pnpm install
pnpm dev:studioUseful source checks and builds:
pnpm test:engine
pnpm build:studioThese are workspace scripts, not a claim that a fresh installation currently passes. At public base 3bfabbf7725cda8904f4dd8518c1edda1a59b074, the observed CI run failed during dependency installation and skipped verification. That is neither a passing verify nor an observed code-test failure.
pnpm verify runs pnpm check, pnpm check:data-f:all, and the workspace tests/builds. check uses biome check --write ., so verification can rewrite files; use a clean, isolated checkout. Desktop development also runs Panda CSS codegen. See the app guide for Storybook and platform packaging commands. Packaging scripts are build entry points, not shipped installers.
Read current contracts and implementation before using prose as an API reference. Historical ADRs explain earlier decisions and may differ from today's contracts; performance wording in older documents should not be treated as a benchmark.
- Current engine reading path: Engine guide · Onboarding · Architecture overview
- App and technical setup: Desktop Studio · English technical spec/troubleshooting · Korean technical spec
- Design history: Root ADRs · Engine ADRs · Desktop ADRs · App-shell and AI deferral record
- Contributor tools: Conventions · Agent prompt tools and CLI · Contributing
agent-tools loads and validates root/package rules and renders prompts with required-reading entries. This helps communicate architecture constraints; it is not proof that agents always comply or that regressions are prevented. Loader · Schema · Renderer