Editor#
@clipkit/editor is an embeddable, open-source timeline editor — a full visual editor over the Clipkit Protocol that you drop into your React app as a single component.
It reads and writes the same CKP/1.0 Source that the runtime, the MCP server, the CLI, and the render service all consume. Whatever an AI agent or a human produces in the editor is the same JSON your renderer eats — one schema, two surfaces.
Install#
npm install @clipkit/editor
It ships as a React 19 component (react and react-dom are peer dependencies), licensed Apache-2.0.
Drop it in#
import { Editor, ADVANCED_CONFIGURATION } from '@clipkit/editor'; import type { Source } from '@clipkit/protocol'; function MyVideoTool({ project }: { project: Source }) { return ( <Editor initialSource={project} configuration={ADVANCED_CONFIGURATION} onSourceChange={(source) => save(source)} /> ); }
initialSource is the only required prop. Persist edits from onSourceChange — it fires with the full Source on every change.
Configurations#
The same component tree ships as two configurations; pass one in, or build your own:
ADVANCED_CONFIGURATION— the full surface: every panel, keyframes, expressions. This is the default when you omit the prop.BASIC_CONFIGURATION— a streamlined editor with the essential views and controls.
import { Editor, BASIC_CONFIGURATION } from '@clipkit/editor'; <Editor initialSource={project} configuration={BASIC_CONFIGURATION} />;
A configuration is data — it decides which views and controls render over the same underlying store (the EditorConfiguration type). One tree, configurations decide.
Props#
| Prop | Type | Notes |
|---|---|---|
initialSource | Source | Required. The composition to open. |
configuration | EditorConfiguration | Defaults to ADVANCED_CONFIGURATION. |
onSourceChange | (source: Source) => void | Fires on every edit — persist the JSON here. |
assetStore | AssetStore | Where uploaded media lives. Defaults to local browser storage. |
onRender | (source, request) => void | Called when the user exports — wire it to your render endpoint. |
theme | 'light' | 'dark' | Defaults to 'dark'; follows the prop live. |
backend | 'auto' | 'webgpu' | 'webgl2' | Preview backend. Defaults to 'auto'. |
Assets and storage#
Media the user adds (images, video, audio) flows through an injected AssetStore port — the editor library itself has zero database code. Two implementations ship in the box:
import { createLocalAssetStore, createMemoryAssetStore } from '@clipkit/editor'; const assetStore = createLocalAssetStore(); // browser IndexedDB — the default
createLocalAssetStore()— persists to the browser (IndexedDB). Used automatically if you pass noassetStore.createMemoryAssetStore()— ephemeral, in-memory (handy for tests).
To put assets in S3, Supabase, or your own API, implement the AssetStore interface and pass it as assetStore.
Preview and export#
Preview runs live in the browser via @clipkit/runtime (WebGPU, with a WebGL2 fallback), and the editor can export MP4 directly in the browser. For server-side or heavier renders, point onRender at:
- a local
@clipkit/rendererinstance, - the hosted API at
api.clipkit.dev, or - your own infrastructure running
@clipkit/renderer.
Editing runs free in the user's browser; rendering is the part you might host or charge for — on your own terms.
Using it outside React#
@clipkit/editor is a React 19 component. If your app is already React — Next.js, Vite, Remix — it's a one-component drop-in. For a non-React page you can mount it imperatively with ReactDOM.createRoot(el).render(<Editor … />), or wrap it through a React-interop bridge for Vue, Svelte, or Angular. There is no separate web-component build today.
License#
Apache-2.0 — self-host, fork, and embed it. Source on GitHub.