Skip to main content
EditorCore is the central singleton that manages all editor state through specialized managers. It provides a consistent API for accessing and manipulating the editor’s functionality.

Architecture overview

The EditorCore singleton coordinates all editor operations through domain-specific managers:

Core implementation

The EditorCore class is implemented as a singleton pattern with private constructor:
apps/web/src/core/index.ts

Manager responsibilities

Each manager handles a specific domain of editor functionality:
Controls video playback state, seeking, and frame navigation.
Manages tracks, elements, and timeline operations like splitting, trimming, and moving elements.
Handles scene creation, switching, deletion, and bookmark management.
Manages project-level state including settings, metadata, and active project.
Handles media asset loading, processing, and management.
Controls video rendering and canvas output.
Implements undo/redo functionality through the command pattern.
Handles auto-saving and project persistence.
Manages audio playback, mixing, and processing.
Tracks selected elements and provides selection utilities.

When to use what

The method you use to access EditorCore depends on your context:
Always use the useEditor() hook:
The hook:
  • Returns the singleton instance
  • Subscribes to all manager changes
  • Automatically re-renders when state changes
Never instantiate EditorCore directly. Always use getInstance() or the useEditor() hook to ensure you’re working with the singleton instance.

The useEditor hook

The useEditor() hook is implemented using React’s useSyncExternalStore to provide reactive state updates:
apps/web/src/hooks/use-editor.ts
The hook subscribes to all manager changes and triggers re-renders when any manager state updates.

Manager subscription pattern

Each manager implements a subscription pattern for reactive updates:

Best practices

Use the right access method

Use useEditor() in React components and getInstance() in utilities.

Access managers directly

Call manager methods directly: editor.timeline.addTrack() instead of going through EditorCore.

Don't create new instances

Never call new EditorCore(). Always use the singleton pattern.

Let managers handle state

Don’t duplicate manager state in local component state.
  • Timeline system - Understanding the TimelineManager
  • Scenes - Working with the ScenesManager
  • Commands - Using the CommandManager for undo/redo
  • Actions - Triggering operations through the actions system