ReactVideoEditor
A modular, drop-in React video editor with sidebar panels, Remotion-powered player, renderer abstraction, autosave, theming, and pluggable media adaptors
The RVE Editor is a composable, drop-in editor shell that wires together the core building blocks of a video editing UI: a Remotion-powered player, a modular sidebar with overlay panels, timeline configuration, autosave hooks, theme management, and a renderer abstraction. You stay in control of data and backends via explicit props and adaptors.
Under the hood, RVE uses Remotion for rendering and playback, and exposes a renderer interface (e.g. HTTP/SSR or Lambda) so you can plug in your own backend. Media sourcing is handled by a flexible adaptor layer (e.g. Pexels), while overlays and timeline config remain app-controlled.
Editor vs Player-only
Use full Editor mode for an all-in-one editing UI (sidebar + editor + autosave). Switch to player-only mode when you just need an embeddable, fullscreen player with overlays and responsive sizing, for example on mobile or preview pages.
Key Features
- Renderer abstraction: Bring your own backend via a simple
VideoRenderer
interface; ships withHttpRenderer
. - Player-only mode: Fullscreen, responsive player without the editor UI for lightweight embeds.
- Modular sidebar: Default sidebar with pluggable overlay panels; disable or replace with your own.
- Autosave hooks:
onSaving
andonSaved
callbacks plus visible autosave status. - Theming: Custom theme registry, default themes toggle, and external theme switching.
- Media adaptors: Plug-in sources for video, images, audio, stickers, templates, and animations.
- Timeline config: Control rows, zoom constraints, snapping behavior, and push-on-drag.
- Responsive video sizing: Aspect ratio and explicit dimension controls for predictable layout.
- Mobile-conscious: Player-only mode includes mobile viewport height handling.
Usage Example
import React from 'react';
import { HttpRenderer } from '@/app/reactvideoeditor/pro/utils/http-renderer';
import { ReactVideoEditor } from '@/app/reactvideoeditor/pro/components/react-video-editor';
import { createPexelsVideoAdaptor } from '@/app/reactvideoeditor/pro/adaptors/pexels-video-adaptor';
import { createPexelsImageAdaptor } from '@/app/reactvideoeditor/pro/adaptors/pexels-image-adaptor';
import { DEFAULT_OVERLAYS } from '@/app/constants';
import { CustomTheme } from '@/app/reactvideoeditor/pro/hooks/use-extended-theme-switcher';
export default function VideoEditorPage() {
const PROJECT_ID = 'MyComposition';
const availableThemes: CustomTheme[] = [
{ id: 'rve', name: 'RVE', className: 'rve', color: '#3E8AF5' },
];
const ssrRenderer = React.useMemo(
() =>
new HttpRenderer('/api/latest/ssr', {
type: 'ssr',
entryPoint: '/api/latest/ssr',
}),
[]
);
return (
<div className="w-full h-screen">
<ReactVideoEditor
projectId={PROJECT_ID}
defaultOverlays={DEFAULT_OVERLAYS}
fps={30}
renderer={ssrRenderer}
disabledPanels={[]}
availableThemes={availableThemes}
defaultTheme="dark"
sidebarWidth="400px"
sidebarIconWidth="57.6px"
showIconTitles={false}
adaptors={{
video: [createPexelsVideoAdaptor('YOUR_PEXELS_API_KEY')],
images: [createPexelsImageAdaptor('YOUR_PEXELS_API_KEY')],
}}
onThemeChange={(themeId) => console.log('Theme changed:', themeId)}
/>
</div>
);
}
Component Structure
ReactVideoEditor/
├── components/
│ ├── core/
│ │ ├── editor.tsx # Main editor surface
│ │ └── video-player.tsx # Remotion-based player
│ ├── shared/
│ │ └── default-sidebar.tsx # Default sidebar with overlay panels
│ ├── autosave/
│ │ └── autosave-status.tsx # Autosave UI indicator
│ ├── providers/
│ │ ├── react-video-editor-provider.tsx # Top-level provider composition
│ │ └── editor-provider.tsx # Core editor context wiring
│ └── ui/ # Sidebar/tooltip/button primitives
├── contexts/
│ ├── editor-context.tsx
│ ├── renderer-context.tsx
│ ├── media-adaptor-context.tsx
│ └── sidebar-context.tsx
├── hooks/
│ ├── use-overlays.tsx
│ ├── use-rendering.tsx
│ └── use-extended-theme-switcher.ts
├── utils/
│ └── http-renderer.ts # HTTP renderer implementing VideoRenderer
├── types/
│ ├── renderer.ts # VideoRenderer interface
│ ├── overlay-adaptors.ts # Overlay adaptor interfaces
│ └── index.ts # OverlayType, Overlay, etc.
└── constants.ts # DEFAULT_OVERLAYS, colors, etc.
Props
The ReactVideoEditor
component extends the editor provider props and adds UI-level controls. Required props are marked with *.
Prop | Type | Default | Description |
---|---|---|---|
Core | |||
projectId * | string | - | Composition/session ID used for renders and state |
renderer * | VideoRenderer | - | Backend implementation (e.g. HttpRenderer ) |
fps | number | 30 | Frames per second for playback and renders |
defaultOverlays | Overlay[] | - | Initial overlay set for the timeline |
Autosave | |||
autoSaveInterval | number | 10000 | Autosave interval in milliseconds |
onSaving | (saving: boolean) => void | - | Called when autosave toggles |
onSaved | (timestamp: number) => void | - | Called after a save completes |
Sidebar and Layout | |||
showSidebar | boolean | true | Toggle the default sidebar |
customSidebar | ReactNode | - | Provide your own sidebar; hides the default |
sidebarLogo | ReactNode | - | Custom logo for the default sidebar |
sidebarFooterText | string | - | Footer text in the default sidebar |
disabledPanels | OverlayType[] | - | Hide specific overlay panels |
showIconTitles | boolean | true | Show/hide sidebar icon titles |
sidebarWidth | string | "16rem" | CSS width var for content sidebar |
sidebarIconWidth | string | "3rem" | CSS width var for icon rail |
className | string | - | Applied to main content inset |
Player / Mode | |||
isPlayerOnly | boolean | false | Fullscreen player without editor UI |
Renderer & API | |||
baseUrl | string | - | Optional API base for editor operations |
Media Adaptors | |||
adaptors | OverlayAdaptors | - | Pluggable sources for content (video, images, audio, text, stickers, templates, animations) |
Timeline | |||
initialRows | number | 5 | Initial number of timeline rows |
maxRows | number | 8 | Maximum number of timeline rows |
Zoom | |||
zoomConstraints | object | { min: 0.2, max: 10, step: 0.1, default: 1 } | Zoom level constraints |
Snapping | |||
snappingConfig | object | { thresholdFrames: 1, enableVerticalSnapping: true } | Timeline snapping configuration |
Feature Flags | |||
disableMobileLayout | boolean | false | Disable mobile-specific layout |
disableVideoKeyframes | boolean | false | Disable video keyframe functionality |
enablePushOnDrag | boolean | false | Enable push-on-drag timeline behavior |
Video Dimensions | |||
videoWidth | number | 1280 | Video output width |
videoHeight | number | 720 | Video output height |
Theming | |||
availableThemes | CustomTheme[] | - | List of custom themes |
selectedTheme | string | undefined | - | Active theme id |
onThemeChange | (themeId: string) => void | - | Theme change callback |
showDefaultThemes | boolean | true | Show/hide default themes |
hideThemeToggle | boolean | false | Hide theme toggle UI |
defaultTheme | string | "dark" | Default theme to use |
Status UI | |||
showAutosaveStatus | boolean | true | Show autosave indicator |
Notes
- The component internally manages a
playerRef
and wires it into theVideoPlayer
. If you need direct player access, read it from the editor context or adapt the provider usage directly. DEFAULT_OVERLAYS
andOverlayType
are exported fromconstants
andtypes
, respectively, and can seed the editor with initial content.- The
HttpRenderer
is a convenience implementation ofVideoRenderer
that expects REST endpoints at/render
and/progress
.
Next Steps
- Get started with the default sidebar panels and overlays.
- Wire up your own renderer (SSR or Lambda) implementing
VideoRenderer
. - Add media sources via
adaptors
(e.g. Pexels for images/videos). - Customize themes and integrate your app's theme switching UX.