Screen Recorder Mode
Add the RVE screen-recording tools to your editor and load a recorded screen, camera, and cursor track
Screen Recorder mode changes the editor for recorded-screen workflows. It adds one focused General panel for backgrounds, screen framing, camera layouts, borders, cursor styling, and cursor-follow zoom.
You can start with one prop and one screen video. Add camera and cursor data only when your recorder supplies them.
SDK version
Use @reactvideoeditor/react-video-editor 5.13.13 or later for all controls in this guide. Screen Recording Tools started in 5.13.0 and remain a beta API.
What the SDK does
When screenRecordingTools is true, the SDK:
- Adds a General panel and opens it when the editor loads.
- Gives the screen video controls for padding, roundness, shadow, and borders.
- Adds colour, gradient, image, and built-in wallpaper backgrounds.
- Shows camera layout and framing controls when a camera item exists.
- Shows cursor style and automatic zoom controls when the screen item has pointer data.
- Adds a Cursor panel when the screen item has pointer data.
- Sets the default sidebar width to
400px(the standard default is256px). You can set a different width withsidebarWidth. - Hides the aspect-ratio and playback-speed controls by default. You can show them again with
timelineHeaderConfig.
The sidebar panel ids for this mode are general and pointer. You can add them to disabledPanels to hide the panels.
The SDK does not capture the screen. Your web app, Electron app, or native app records the media and then passes it to RVE as editorState.
Quick start
1. Capture or load a screen video
Use the capture system that fits your product:
- In a browser, use
navigator.mediaDevices.getDisplayMedia()andMediaRecorder. - In Electron, use the Electron desktop capture APIs or a native capture process.
- In a native app, record the screen and give the React view a browser-playable media URL.
Read the recorded file's width, height, and duration before you create the editor state.
Media URLs
A blob URL is suitable for the current browser session, but it does not work after a reload. Upload the recording or save it through a local media adaptor before you persist the project. A cloud renderer must be able to read every media URL.
2. Create the first editor state
This helper creates one screen item. It is enough to use backgrounds, framing, borders, shadows, and standard timeline edits.
import {
ItemType,
type EditorState,
type VideoItem,
} from '@reactvideoeditor/react-video-editor/types';
type ScreenRecording = {
src: string;
width: number;
height: number;
durationInSeconds: number;
};
export function createScreenRecordingState(
recording: ScreenRecording,
fps = 30,
): EditorState {
const dimensions = { width: 1920, height: 1080 };
const screen: VideoItem = {
id: crypto.randomUUID(),
type: ItemType.VIDEO,
content: recording.src,
src: recording.src,
from: 0,
durationInFrames: Math.max(1, Math.ceil(recording.durationInSeconds * fps)),
mediaSrcDuration: recording.durationInSeconds,
sourceAspectRatio: recording.width / recording.height,
left: 160,
top: 90,
width: 1600,
height: 900,
rotation: 0,
styles: {
objectFit: 'contain',
borderRadius: '1%',
volume: 1,
},
};
return {
tracks: [
{
id: crypto.randomUUID(),
name: 'Screen',
items: [screen],
magnetic: false,
muted: false,
visible: true,
},
],
dimensions,
background: { type: 'color', value: '#111827' },
playbackRate: 1,
savedAt: Date.now(),
};
}3. Turn on Screen Recorder mode
'use client';
import { ReactVideoEditor } from '@reactvideoeditor/react-video-editor/react-video-editor';
import type { EditorState } from '@reactvideoeditor/react-video-editor/types';
import '@reactvideoeditor/react-video-editor/styles.css';
export function ScreenRecordingEditor({ state }: { state: EditorState }) {
return (
<main style={{ height: '100vh' }}>
<ReactVideoEditor
projectId="screen-recording"
editorState={state}
screenRecordingTools
fps={30}
onSave={(nextState) => {
// Save nextState to your project store.
console.log(nextState);
}}
/>
</main>
);
}This is the full basic setup. Do not add the optional data below until your capture layer produces it.
Add a camera recording
Add the camera as a second VideoItem and set mediaRole: 'camera'. This value tells RVE to show camera shapes, framing, shadow, and layout presets.
import {
ItemType,
type CameraVideoItem,
} from '@reactvideoeditor/react-video-editor/types';
const camera: CameraVideoItem = {
id: crypto.randomUUID(),
type: ItemType.VIDEO,
mediaRole: 'camera',
camera: {
shape: 'square',
sourceAspectRatio: cameraWidth / cameraHeight,
shrinkOnCursorZoom: true,
},
content: cameraUrl,
src: cameraUrl,
from: cameraStartFrame,
durationInFrames: screenDurationInFrames - cameraStartFrame,
mediaStartTime: cameraMediaStartTime,
mediaSrcDuration: cameraDurationInSeconds,
left: 1530,
top: 770,
width: 270,
height: 270,
rotation: 0,
styles: { objectFit: 'cover', volume: 1, zIndex: 100 },
};Record the screen and camera against the same clock. Use from when the camera starts after the screen. Use mediaStartTime when the camera file starts before the screen file.
Camera fields
The camera object holds the camera settings. The Camera panel writes these values. You can also set them in your initial state.
| Field | Type | Default | Description |
|---|---|---|---|
shape | 'square' | 'horizontal' | 'vertical' | 'original' | 'square' | The frame shape of the camera. |
sourceAspectRatio | number | - | The width divided by the height of the camera file. |
shadow | number | 75 in the panel | The shadow strength, from 0 (off) to 100. |
shrinkOnCursorZoom | boolean | true | Make the camera a smaller square while a cursor zoom is active. |
zoom | { level: number; targetX: number; targetY: number } | { level: 1, targetX: 50, targetY: 50 } | The framing of the camera video in its frame. The panel sets level from 1 to 4. targetX and targetY are percentages from 0 to 100. |
layout | object | - | The active two-item layout. The Camera panel writes this value. |
Camera layout presets
The Camera panel has five layout presets. A preset puts the screen and the camera in fixed positions on the canvas:
| Preset | Panel label | Canvas |
|---|---|---|
camera-overlay | Camera over screen | 16:9 |
camera-bottom | Camera bottom | 9:16 |
camera-top | Camera top | 9:16 |
camera-left | Camera left | 16:9 |
camera-right | Camera right | 16:9 |
A preset stores the original positions of the two items in camera.layout. The user can reset the layout to go back to those positions. The padding field sets the space around the items. Let the panel write the layout object. Do not build it by hand.
Add an editable cursor and automatic zoom
Attach a PointerTrack to the screen VideoItem. RVE uses the samples for cursor playback. It uses the click events to create the first automatic zoom range.
import type { PointerTrack } from '@reactvideoeditor/react-video-editor/types';
const pointer: PointerTrack = {
version: 1,
sourceWidth: recording.width,
sourceHeight: recording.height,
samples: [
{ timeMs: 0, x: 0.25, y: 0.40, visible: true },
{ timeMs: 100, x: 0.28, y: 0.42, visible: true },
],
events: [
{
id: crypto.randomUUID(),
timeMs: 100,
type: 'down',
button: 'primary',
x: 0.28,
y: 0.42,
},
],
settings: {
visible: true,
style: 'black',
size: 1.5,
clickEffect: true,
},
};
screen.pointer = pointer;The x and y values must be in the range from 0 to 1. Times are milliseconds from the start of the screen source file. Keep samples in time order.
After the data is present, the General panel lets the user change the cursor size, turn on automatic zoom, set the zoom level, and set the zoom speed. The Cursor panel also has the cursor style and the click effect controls.
Pointer settings
The settings object of the PointerTrack controls the cursor:
| Field | Type | Default | Description |
|---|---|---|---|
visible | boolean | - | Show the cursor. |
style | 'black' | 'white' | 'dot' | 'highlight' | - | The cursor style. |
size | number | 1.5 | The cursor scale. |
clickEffect | boolean | - | Show an effect at each click. |
clickColor | string | '#7c5cff' | The color of the click effect. The panel has purple, red, amber, green, and blue. |
clickSize | number | 1 | The scale of the click effect. The panel sets a value from 0.5 to 2. |
Zoom items
A zoom is a timeline item with type: ItemType.ZOOM. Its type is ZoomItem. A zoom item does not show content. It zooms the video canvas for the duration of the item.
There are two types of zoom:
- A scene zoom zooms to a fixed point. Set
styles.zoomTypeto'in','out','in-out', or'shake'. - A cursor zoom follows the recorded cursor. Set
styles.zoomTypeto'follow'and setstyles.followPointerItemIdto the id of the screenVideoItem.
The zoom styles have these fields:
| Field | Applies to | Description |
|---|---|---|
zoomLevel | All zooms | The scale factor. For example, 1.5 is 150%. |
targetX, targetY | All zooms | The zoom point as a percentage from 0 to 100. The default is 50. |
easing | All zooms | 'linear', 'ease-in', 'ease-out', or 'ease-in-out'. |
followPointerItemId | Cursor zoom | The id of the video item that has the pointer data. |
followTransitionDuration | Cursor zoom | The zoom-in and zoom-out time in seconds. The default is 0.8. |
followTransitionIn, followTransitionOut | Cursor zoom | Turn the enter or exit transition on or off. The default for both is true. |
When the user turns on automatic zoom, the editor adds a cursor zoom item. The item covers the recorded clicks and uses a zoomLevel of 1.6. You can also add a cursor zoom in your initial state:
import { ItemType, type ZoomItem } from '@reactvideoeditor/react-video-editor/types';
const cursorZoom: ZoomItem = {
id: crypto.randomUUID(),
type: ItemType.ZOOM,
content: 'Cursor zoom',
from: 0,
durationInFrames: screen.durationInFrames,
left: 0,
top: 0,
width: 0,
height: 0,
rotation: 0,
styles: {
opacity: 1,
zoomType: 'follow',
followPointerItemId: screen.id,
zoomLevel: 1.6,
targetX: 50,
targetY: 50,
easing: 'ease-in-out',
followTransitionDuration: 0.8,
},
};Put the zoom item on its own track in editorState.tracks.
Timeline snapping
The Settings panel has a Snapping switch in the Timeline section. When snapping is on, items snap to the edges of other items during a drag. Turn it off to move items freely. Item positions and durations stay on whole frames in both cases.
Mode props
These props control the recorder experience:
| Prop | Type | Default | Use |
|---|---|---|---|
screenRecordingTools | boolean | false | Add and open the recorder-specific General panel. This API is in beta. |
editorState | EditorState | - | Load the screen, optional camera, pointer data, background, and dimensions. |
timelineHeaderConfig | TimelineHeaderConfig | Mode defaults | Show or hide the aspect-ratio and playback-speed controls. Both are hidden in Screen Recorder mode by default. |
sidebarWidth | string | '400px' in this mode | Set the sidebar width. The default is '256px' when screenRecordingTools is false. |
disabledPanels | string[] | [] | Hide sidebar panels. Use general and pointer for the recorder panels. |
enableCanvasZoom | boolean | true | Let users zoom and pan the editor canvas. This does not control zoom effects in the exported video. |
mediaLibrary | MediaLibraryConfig | Derived | Set the Stock and My Library tabs when you want custom media sources. |
For example, show the aspect-ratio selector but keep the playback-speed selector hidden:
<ReactVideoEditor
projectId="screen-recording"
editorState={state}
screenRecordingTools
timelineHeaderConfig={{
showAspectRatioControls: true,
showPlaybackSpeedControls: false,
}}
/>Reference product pattern
Screen Recorder uses this same boundary:
- A native capture process records the screen and audio.
- The app records the camera separately and keeps both start times.
- The capture process saves timed pointer samples and click events.
- The app creates screen, camera, and cursor-zoom tracks in
EditorState. - The app opens
ReactVideoEditorwithscreenRecordingTools.
This design keeps capture code outside the SDK. It also lets the editor work with browser, Electron, or native capture systems.
Production checklist
- Save permanent media URLs before you save the editor state.
- Keep the screen and camera start times so the tracks stay synchronized.
- Keep source width and height with pointer data.
- Set CORS headers on remote media for browser export.
- Use even output dimensions for H.264 export.
- Test one real recording through capture, edit, save, reload, and export.
For a working product reference, see Screen Recorder and the screen-recorder use case.