Proposal: browser extension support via a native messaging host
Summary
I would like to add optional browser extension support to Recordly, so a user can start, pause and stop a recording from a toolbar button in Chrome/Edge/Firefox without switching to the HUD.
Before writing any code I want to check whether this is wanted at all, and if so, agree on the transport. That decision drives almost all of the work, so I would rather settle it here than in review.
Why
The common case for a demo video is recording a browser. Today that means leaving the tab, finding the HUD, and starting there, which is exactly the context switch the app otherwise tries to remove. Screen Studio and Loom both ship extensions for this reason.
To be clear about scope: this is not about recording inside the browser. Capture would stay entirely native (ScreenCaptureKit / WGC). The extension would only be a remote control.
What exists today
I looked for an existing integration surface and did not find one:
- No custom protocol handler. No
setAsDefaultProtocolClient, no open-url handler, and no protocols entry in electron-builder.json5.
- No
globalShortcut registrations.
- No native messaging host.
electron/mediaServer.ts is not usable as a control channel: it binds with server.listen(0, ...), so the port changes every launch; it only answers GET/HEAD/OPTIONS on /video; and paths are gated by isAllowedMediaPath against an allowlist. It is a playback file server, by design.
So an extension currently has no way to reach the app, and this would mean adding one.
What does already exist, and is the useful precedent, is an external trigger into the recorder: stop-recording-from-tray. The recording IPC surface (electron/ipc/register/recording.ts) already exposes start-native-screen-recording, pause-native-screen-recording, stop-native-screen-recording and start-countdown. A browser extension would be another caller of those same paths, not a new recording implementation.
Proposed approach: native messaging host
Chrome's standard extension-to-desktop mechanism. A JSON host manifest points at a small native binary, and the browser pipes JSON over stdio.
Why this over the alternatives:
- No open network port. Nothing for another local process or web page to reach.
- The browser enforces which extension IDs may connect, via
allowed_origins in the host manifest.
- The OS handles install-time trust, rather than us inventing a pairing scheme.
Rejected alternatives, and why:
- Local HTTP control port with a pairing token. Much easier to prototype, works in every browser, but it means running an authenticated control server that can start a screen recording. Any mistake in origin or token handling turns into "a web page can record your screen". I do not think that trade is worth it, and I would expect it to be rejected on those grounds.
chrome.tabCapture in the extension. Needs no desktop changes, but the extension would be producing the video, so there is no cursor telemetry and therefore no auto-zoom and no cursor effects. That discards the main reason to use Recordly, so it defeats the purpose.
Scope
Roughly, if this goes ahead:
- Native messaging host binary and manifest, plus registration in the installers for macOS, Windows and Linux. This is the bulk of the work and the part with real cross-platform risk.
- A thin main-process bridge translating host messages into the existing recording IPC calls. Deliberately no new recording logic.
- The extension itself: start/pause/stop, plus recording state feedback.
- Docs, and tests for the bridge layer.
I would expect to split this across several PRs rather than land it as one, starting with the bridge and host behind a setting that is off by default.
Questions
- Do you want this in Recordly at all? A "no" now is genuinely more useful to me than a closed PR later.
- If yes, is native messaging the right transport, or do you have a different preference?
- Should the extension live in this repo or a separate one?
- Would you want it off by default behind a setting?
Happy to prototype the bridge against the existing IPC first, so there is something concrete to look at before committing to installer work.
Proposal: browser extension support via a native messaging host
Summary
I would like to add optional browser extension support to Recordly, so a user can start, pause and stop a recording from a toolbar button in Chrome/Edge/Firefox without switching to the HUD.
Before writing any code I want to check whether this is wanted at all, and if so, agree on the transport. That decision drives almost all of the work, so I would rather settle it here than in review.
Why
The common case for a demo video is recording a browser. Today that means leaving the tab, finding the HUD, and starting there, which is exactly the context switch the app otherwise tries to remove. Screen Studio and Loom both ship extensions for this reason.
To be clear about scope: this is not about recording inside the browser. Capture would stay entirely native (ScreenCaptureKit / WGC). The extension would only be a remote control.
What exists today
I looked for an existing integration surface and did not find one:
setAsDefaultProtocolClient, noopen-urlhandler, and noprotocolsentry inelectron-builder.json5.globalShortcutregistrations.electron/mediaServer.tsis not usable as a control channel: it binds withserver.listen(0, ...), so the port changes every launch; it only answersGET/HEAD/OPTIONSon/video; and paths are gated byisAllowedMediaPathagainst an allowlist. It is a playback file server, by design.So an extension currently has no way to reach the app, and this would mean adding one.
What does already exist, and is the useful precedent, is an external trigger into the recorder:
stop-recording-from-tray. The recording IPC surface (electron/ipc/register/recording.ts) already exposesstart-native-screen-recording,pause-native-screen-recording,stop-native-screen-recordingandstart-countdown. A browser extension would be another caller of those same paths, not a new recording implementation.Proposed approach: native messaging host
Chrome's standard extension-to-desktop mechanism. A JSON host manifest points at a small native binary, and the browser pipes JSON over stdio.
Why this over the alternatives:
allowed_originsin the host manifest.Rejected alternatives, and why:
chrome.tabCapturein the extension. Needs no desktop changes, but the extension would be producing the video, so there is no cursor telemetry and therefore no auto-zoom and no cursor effects. That discards the main reason to use Recordly, so it defeats the purpose.Scope
Roughly, if this goes ahead:
I would expect to split this across several PRs rather than land it as one, starting with the bridge and host behind a setting that is off by default.
Questions
Happy to prototype the bridge against the existing IPC first, so there is something concrete to look at before committing to installer work.