Recording the screen with two browser APIs
A whole screen recorder fits in about a dozen lines of browser API. Bilal Hussain put it together, and it's worth knowing because it runs entirely on the device, no server, no upload. Try it (desktop Chromium or Firefox):
Your screen recording preview shows here
Two APIs, three steps
First, getDisplayMedia opens the OS picker and returns a stream of whatever
the user selects:
const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });Then MediaRecorder records that stream into chunks, and on stop you stitch the
chunks into a Blob:
const chunks = [];
const rec = new MediaRecorder(stream, { mimeType: "video/webm" });
rec.ondataavailable = (e) => e.data.size && chunks.push(e.data);
rec.onstop = () => {
const url = URL.createObjectURL(new Blob(chunks, { type: "video/webm" }));
// play it, or set it as an <a download> href
};
rec.start();Point a <video> at the stream while recording for a live preview, swap in the
Blob URL when you stop, and you've got record, playback, and download.
Two things not to forget
Stop the tracks when you're done, or the browser keeps flashing its "you're sharing your screen" banner long after you've finished:
stream.getTracks().forEach((t) => t.stop());And listen for the video track's ended event. The user can end the share from
the browser's own controls, not just your stop button, and you want to react to
both the same way.
stream.getVideoTracks()[0].addEventListener("ended", stopRecording);Support is desktop Chromium and Firefox. Mobile browsers don't expose
getDisplayMedia, so feature-detect it and hide the button where it's missing.
Inspired by Bilal Hussain. Grab the component on the Screen Recorder page.
Ask your agent to implement this
Read the full writeup at https://seangeng.com/writing/recording-the-screen-in-the-browser.md and implement it in my project.
It covers: Recording the screen with two browser APIs — getDisplayMedia grabs a stream of the screen, window, or tab; MediaRecorder captures it to a webm you can play back and download. A full screen recorder, no libraries, nothing uploaded.
Requirements:
- Follow the technique/approach exactly as described in the writeup.
- Adapt names, colors, and styling to my project's existing conventions.
- If it's a component, make it reusable with sensible props and TypeScript types.
- Keep it accessible: semantic HTML, keyboard support, and respect prefers-reduced-motion.
- When done, tell me which files you created or changed and how to use it.Paste into Claude Code, Codex, Cursor, or any agent. view raw .md download source .zip