Skip to main content
This guide walks you through creating your first webreel recording from scratch, explaining the core concepts and workflow.

Quick Start

The fastest way to get started is with the init command:
npx webreel init --name my-demo --url https://example.com
This creates a webreel.config.json file with a basic structure:
{
  "$schema": "https://webreel.dev/schema/v1.json",
  "videos": {
    "my-demo": {
      "url": "https://example.com",
      "viewport": { "width": 1080, "height": 1080 },
      "steps": []
    }
  }
}

Understanding the Config Structure

Top-Level Fields

FieldTypeDescription
$schemastringJSON Schema URL for IDE autocompletion and validation
outDirstringOutput directory for videos (default: videos/)
baseUrlstringPrepended to relative URLs in video configs
viewportobjectDefault viewport dimensions for all videos
defaultDelaynumberDefault delay (ms) after each step
videosobjectObject mapping video names to their configurations

Video Configuration

Each video in the videos object has these key fields:
FieldRequiredDescription
urlYesThe URL to record. Can be absolute (https://...), relative, or local file path (./web/index.html)
viewportNoBrowser viewport dimensions as {"width": 1920, "height": 1080}
zoomNoCSS zoom level (e.g., 2 for 2x zoom, useful for higher quality output)
waitForNoCSS selector to wait for before starting recording
stepsYesArray of actions to perform during the recording

Building Your First Recording

1
Create the config file
2
Start with a minimal configuration:
3
{
  "$schema": "https://webreel.dev/schema/v1.json",
  "videos": {
    "hello-world": {
      "url": "https://example.com",
      "viewport": { "width": 1920, "height": 1080 },
      "zoom": 2,
      "waitFor": ".cta",
      "steps": []
    }
  }
}
4
Add a pause step
5
Start with a brief pause to let viewers see the initial state:
6
"steps": [
  { "action": "pause", "ms": 500 }
]
7
Add a click action
8
Click a button or link using either a CSS selector or visible text:
9
"steps": [
  { "action": "pause", "ms": 500 },
  { "action": "click", "selector": "a.cta", "delay": 1000 }
]
10
The delay field adds a pause after the click completes.
11
Record the video
12
Run the recording:
13
npx webreel record
14
Your video will be saved to videos/hello-world.mp4.

The Recording Workflow

Understanding how webreel processes your configuration helps you create better recordings:
1
Page Load
2
Webreel launches a headless Chrome instance and navigates to your specified URL.
3
Wait for Ready
4
If you specified a waitFor selector, webreel waits up to 30 seconds for that element to appear before starting.
5
Cursor Initialization
6
The cursor starts at a random position just outside the viewport edge (creating a natural entry motion).
7
Step Execution
8
Each step in your steps array executes sequentially with realistic timing and cursor animation.
9
Frame Capture
10
Screenshots are captured at 60fps during recording and encoded with ffmpeg.
11
Overlay Composition
12
Cursor and keystroke HUD overlays are composited onto the final video.

Common Step Types

Pause

Wait for a specific duration:
{ "action": "pause", "ms": 1200 }

Click

Click an element by selector or text:
{ "action": "click", "selector": "button.primary" }
{ "action": "click", "text": "Get Started" }

Type

Type text into a focused input:
{
  "action": "type",
  "text": "[email protected]",
  "selector": "#email",
  "charDelay": 40
}

Key Press

Press keyboard shortcuts:
{ "action": "key", "key": "cmd+s" }
{ "action": "key", "key": "Enter" }

Tips for Getting Selectors

  1. Open your target page in Chrome
  2. Right-click the element you want to interact with
  3. Select “Inspect”
  4. In the Elements panel, right-click the highlighted element
  5. Choose CopyCopy selector
This gives you a CSS selector you can use in your config.
Instead of selectors, you can target elements by their visible text:
{ "action": "click", "text": "Sign In" }
Webreel finds the smallest element containing that exact text. This is more resilient to markup changes.
When multiple elements match, narrow the search with within:
{
  "action": "click",
  "text": "Delete",
  "within": ".modal"
}
This only searches within elements matching .modal.

Building Up Your Script Incrementally

The most effective way to create complex recordings is to build them step by step:
1
Start with navigation
2
{
  "steps": [
    { "action": "pause", "ms": 500 }
  ]
}
3
Record this to verify the page loads correctly.
4
Add one interaction
5
{
  "steps": [
    { "action": "pause", "ms": 500 },
    { "action": "click", "selector": "#menu-button" }
  ]
}
6
Record and verify the click works.
7
Add the next step
8
Continue adding steps one at a time, recording after each addition:
9
{
  "steps": [
    { "action": "pause", "ms": 500 },
    { "action": "click", "selector": "#menu-button" },
    { "action": "click", "text": "Settings", "delay": 800 }
  ]
}
10
Adjust timing
11
Once all steps work, fine-tune delays for better pacing:
12
{
  "steps": [
    { "action": "pause", "ms": 800 },
    { "action": "click", "selector": "#menu-button", "delay": 400 },
    { "action": "click", "text": "Settings", "delay": 1200 }
  ]
}

Preview Mode

Use preview mode to test your steps in a visible browser without recording:
npx webreel preview
This is faster than recording and lets you debug selector issues interactively.

Watch Mode

During development, use watch mode to automatically re-record when your config changes:
npx webreel record --watch
Edit your webreel.config.json and save, and webreel will immediately re-record your video.

Complete Example

Here’s a complete configuration from the hello-world example:
{
  "$schema": "https://webreel.dev/schema/v1.json",
  "videos": {
    "hello-world": {
      "url": "./web/index.html",
      "viewport": { "width": 1920, "height": 1080 },
      "zoom": 2,
      "waitFor": ".cta",
      "steps": [
        { "action": "pause", "ms": 500 },
        { "action": "click", "selector": "a.cta", "delay": 1000 }
      ]
    }
  }
}
Run with:
npx webreel record

Next Steps

Cursor and Overlays

Customize cursor appearance and keystroke HUD

Output Formats

Learn about MP4, GIF, and WebM output options

Advanced Actions

Master drag-and-drop, scrolling, and complex interactions

API Reference

Complete reference for all available actions

Build docs developers (and LLMs) love