Turn any browser workflow into a polished, shareable tutorial — in seconds.
Browser Tutorial Recorder is a Chrome extension (Manifest V3) that records your clicks, typing, navigation, and form interactions, then lets you edit, annotate, and export the workflow as a step-by-step guide in 7 formats.
Everything stays on your device. No accounts, no cloud uploads, no telemetry.
Version: v2.3.0 — a complete, from-scratch rewrite of the recording engine built for reliability.
Record once, share forever. Click Start, do your workflow, click Stop. Every meaningful interaction becomes a step with a smart, auto-generated description — Click "Submit", Type "[email protected]" into "Email" — showing the full current view with a click marker stamped on the image, exactly like Scribe and Tango.
Edit like a pro. Nine annotation tools (highlight, rectangle, circle, arrow, text, blur, redaction, spotlight, numbered markers), crop, merge, split, duplicate, reorder by drag, and a 60-step undo history.
Export anywhere. Standalone HTML, PDF/Print, animated GIF, Markdown, PNG, JSON, or plain text. Blur and redaction are baked in destructively — hidden content cannot be recovered.
Privacy-first. Password fields and sensitive inputs (configurable keywords) are masked on-page during recording, so secrets never reach a screenshot.
- One-click recording with a live toolbar badge showing the step count
- Action-focused event capture: CLICK, DOUBLE_CLICK, RIGHT_CLICK, MIDDLE_CLICK, TYPE (with the typed text), SELECT, CHECKBOX, RADIO, SUBMIT, KEYBOARD, DROP, NAVIGATION, NEW_TAB — scrolling is positioning, not a step; a "Navigate to …" opener step starts every tutorial
- Fire-and-forget event pipeline — user actions are never dropped waiting on a screenshot
- Clean, professional screenshots — recorder UI is hidden during capture, steps keep the full current view by default (Scribe-style element close-ups are an opt-in in Settings), and the click marker is stamped onto the image by the service worker for a consistent look
- Customizable cursor highlight — pick a preset (classic ring, small yellow filled circle with blur, high-visibility, …) or fine-tune color, size, fill strength and glow in Settings, with a live preview; the live recording ring and the stamped marker always match
- Multi-tab support — follows your workflow across tabs and new windows automatically
- SPA navigation capture — records
history.pushState/hashchange(React, Vue, Angular) - Smart double-click detection via
event.detail(browser-authoritative) - Submit retraction — a SUBMIT following a CLICK on the same element retracts the redundant CLICK step
- Auto-pause on idle (configurable 0–600s timeout)
- Sensitive field masking — password fields and keyword-matched inputs are covered by opaque overlays while recording, including inside shadow DOM and iframes
- Excluded domains — recording pauses on listed domains (applies mid-recording)
- Iframe support — clicks inside iframes are located via same-origin walk or a cross-origin postMessage handshake
- Discard option — "Discard" deletes the in-progress recording instantly
- 9 annotation tools: highlight, rectangle, circle, arrow, text, blur, redaction, spotlight, numbered markers (sequential across the whole tutorial, with a "Next #" control to restart the series anywhere)
- Step management: crop (8-handle marquee: drag inside to move, outside to redraw, live W×H readout; annotations re-anchored), merge with next, split, duplicate, pointer-based drag-to-reorder
- Readable full-page captures — the editor opens screenshots fit-width by default (a 12,000 px tall page fills the pane and scrolls instead of shrinking into an unrecognizable strip), with zoom in/out buttons, Ctrl+wheel, fit-page mode and keyboard shortcuts
- Annotation presets — save and reuse your favorite styles
- Undo / redo with 60-step history (screenshots stored by reference — no memory bloat)
- Recapture — re-take a step's screenshot (viewport or scroll-stitched full page)
- Fully customizable keyboard shortcuts with conflict detection
- Auto-save with visible "Saved ✓" feedback
- 7 formats: standalone HTML, PDF/Print, animated GIF, Markdown, plain text, PNG, JSON
- Destructive privacy treatments — blur and redaction are baked into exported images
- GIF encoder — fresh GIF89a + LZW implementation with a web-safe palette
- Unicode-safe filenames
- Search, filter, sort with debounced search
- Bulk operations — multi-select, bulk export, bulk delete
- Grid and list views
- Keyboard shortcut rebinding with conflict detection
- Recording preferences — capture delay, screenshot format, JPEG quality, idle timeout, sensitive keywords, excluded domains
- Appearance — light/dark/system theme, high contrast, GIF frame speed, preview auto-advance speed
- Storage management — export all, import, delete all, storage size indicator
- Guide mode — step-by-step with Previous / Next
- Watch mode — auto-advances at configurable speed
- Download and extract the ZIP from the latest release
- Open
chrome://extensionsin Chrome, Edge, Brave, Arc, or any Chromium browser - Toggle Developer mode on (top-right corner)
- Click Load unpacked and select the extracted folder
- Pin the Browser Tutorial Recorder icon to your toolbar
Click the extension's refresh icon in chrome://extensions after updating. Your existing tutorials are preserved.
- Start recording — click the extension icon, then Start recording
- Do your workflow — navigate, click, type, scroll on any webpage
- Stop recording — click the extension icon, then Stop & save
- Edit & annotate — the editor opens automatically
- Export — click Export ▾ to download as HTML, PDF, GIF, Markdown, or other formats
| Action | Shortcut |
|---|---|
| Start recording | Alt+Shift+R |
| Stop recording | Alt+Shift+S |
| Pause / resume | Alt+Shift+P |
| Open dashboard | Ctrl+Shift+D (Mac: Cmd+Shift+D) |
Reassign global shortcuts at
chrome://extensions/shortcuts.
- No account, no cloud, no telemetry. Every screenshot and tutorial is stored in IndexedDB on your device.
- On-page masking — sensitive fields are covered by opaque overlays before any screenshot is taken; the data is never rendered into pixels.
- Recursive masking — fields inside shadow DOM and same-origin/cross-origin iframes are masked too (each frame masks its own DOM).
- Blur and redaction are destructive on export — the flattened PNG/PDF/GIF cannot be reverse-engineered.
- Excluded domains — recording pauses on listed domains.
- Internal pages blocked —
file://,chrome://, and other internal schemes are never recorded. - Image URL sanitization — all screenshot URLs are validated
data:image/*before use, blockingjavascript:injection.
The v2.0.0 recording engine was rebuilt from scratch around four reliability principles:
- Fire-and-forget event pipeline — content scripts never wait for a response; the background processes events through a serialized capture queue. No
sendResponsechannel races. - Append-only drafts — steps live in memory and flush to IndexedDB incrementally (no multi-megabyte
storage.localrewrites per event). - Always-on masks — sensitive-field overlays exist for the whole recording session, so capture needs zero coordination.
- Crash-safe rehydration — if the service worker restarts mid-recording, the draft is recovered and the session resumes paused.
- Frame-targeted attach handshake — content scripts say hello once per document; the background replies to the sending frame only, so the attach exchange can never ping-pong (the crash fixed in v2.0.1).
- Lifecycle-hardened session — a 20 s keep-alive ping holds the service worker open for the whole recording, and if the worker ever restarts mid-session the draft resumes recording automatically instead of silently pausing (the lost-steps bug fixed in v2.0.2).
- Sessions live in the service worker via
recorder-core.js(pure state machine, fully unit-tested) - Light UI state mirrors to
chrome.storage.sessionfor the popup - Steps flush to an IndexedDB draft (debounced 400 ms) and finalize into a tutorial on Stop
.
├── manifest.json # MV3 manifest
├── background.js # Service worker — session wiring, capture queue, messages
├── recorder-core.js # Pure recording state machine (unit-tested)
├── content.js # Content script — events, masks, iframe offsets, SPA nav
├── shared.js # IndexedDB + normalization + sanitization helpers
├── settings-store.js # Settings defaults, sync, shortcut logic
├── common-ui.js # Shared helpers for extension pages
├── popup.{html,js,css} # Toolbar popup UI
├── dashboard.{html,js,css} # Tutorial library — search, sort, bulk ops
├── editor.{html,js,css} # Step editor — 9 annotation tools, crop, undo
├── preview.{html,js,css} # Guide / watch mode playback
├── settings.{html,js,css} # Settings tabs
├── print-export.{html,js,css} # Print / PDF export layout
├── exporter.js # Renders annotated canvas + exports 7 formats
├── annotation-geom.js # Pure annotation hit/rotate/crop geometry (unit-tested)
├── gif-encoder.js # GIF89a + LZW encoder
├── theme-boot.js, theme.css # Theme bootstrap + variables
├── test-suite.mjs # Automated test suite (260 tests)
├── package.json # Node dev dependencies (jsdom for tests)
├── .github/workflows/ci.yml # CI workflow
└── icons/ # Extension icons (16/32/48/128 PNG)
- 517 automated tests covering
recorder-core.js,shared.js,settings-store.js,gif-encoder.js,exporter.js,cursor-marker.js,annotation-geom.js, the realcontent.js(evaluated in jsdom), the full background ⇄ content message bus, and a static import/export cross-check of every module - Static analysis — all JS files pass
node --checksyntax validation - CI workflow — tests auto-run on every push and pull request via GitHub Actions
- Fork the repo
- Create a feature branch:
git checkout -b feat/my-feature - Make your changes. Run
npm testto verify tests pass - Commit with a clear message
- Open a PR describing the change
MIT — see LICENSE.