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:PlaybackManager
PlaybackManager
Controls video playback state, seeking, and frame navigation.
TimelineManager
TimelineManager
Manages tracks, elements, and timeline operations like splitting, trimming, and moving elements.
ScenesManager
ScenesManager
Handles scene creation, switching, deletion, and bookmark management.
ProjectManager
ProjectManager
Manages project-level state including settings, metadata, and active project.
MediaManager
MediaManager
Handles media asset loading, processing, and management.
RendererManager
RendererManager
Controls video rendering and canvas output.
CommandManager
CommandManager
Implements undo/redo functionality through the command pattern.
SaveManager
SaveManager
Handles auto-saving and project persistence.
AudioManager
AudioManager
Manages audio playback, mixing, and processing.
SelectionManager
SelectionManager
Tracks selected elements and provides selection utilities.
When to use what
The method you use to access EditorCore depends on your context:- In React components
- Outside React
Always use the The hook:
useEditor() 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
TheuseEditor() hook is implemented using React’s useSyncExternalStore to provide reactive state updates:
apps/web/src/hooks/use-editor.ts
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.
Related concepts
- Timeline system - Understanding the TimelineManager
- Scenes - Working with the ScenesManager
- Commands - Using the CommandManager for undo/redo
- Actions - Triggering operations through the actions system