Puppeteer Screen Recording: How to Capture and Save a Recording
Use Puppeteer’s current `Page.record()` API to capture page activity as an MP4, save the recording, and clean up reliably—even when an interaction fails.
Use Puppeteer’s page.record() method to capture browser page activity as an MP4 video stream. Pass a file path, run the interactions you want to record, then call await recording.stop() before closing the browser. Always stop the recording in a finally block so an exception does not skip cleanup.
This records a video of a page in Chrome. It does not create a replayable script of user actions or a stream of individual screenshots.
1. Record a Puppeteer page to an MP4 file
The current Puppeteer API reference documents Page.record() for recording a page using Chrome DevTools Protocol’s screen-recording API. Its example passes a path such as recording.mp4 and stops the recording through the returned object. See the Puppeteer Page.record() reference.
Install Puppeteer in a Node.js project if it is not already installed:
npm install puppeteer
Save this as record-page.mjs and run it with node record-page.mjs:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://www.example.com', { waitUntil: 'networkidle2' });
const recording = await page.record({ path: 'recording.mp4' });
try {
// Perform the actions you want included in the video.
await page.waitForTimeout(1000);
await page.click('a');
await page.waitForTimeout(1500);
} finally {
await recording.stop();
}
} finally {
await browser.close();
}
Replace the example URL and interactions with the page and actions you need to capture. The waits in this sample are there to make the example’s navigation and interaction sequence easy to follow; choose waits that match your page. The essential sequence is to start recording, perform the desired actions, stop the recording, and then close the browser.
Why stop the recording explicitly?
page.record() returns a recording object. The documented workflow calls await recording.stop() to finish. If a click, navigation, or other operation throws while recording, a finally block still reaches the stop call. The outer finally also closes the browser if setup or page actions fail.
2. What gets saved, and how the stream works
The Puppeteer reference describes the result as an MP4 video stream. The path-based example is the simplest way to save it to a file. The returned ScreenRecording extends ReadableStream<Uint8Array> and documents pipe(destination) and stop(). See the ScreenRecording reference for the returned object’s API.
If your application needs to consume the recording as a stream, use the documented stream methods and the reference for the Puppeteer version installed in your project. The path example establishes file output; it does not, by itself, specify a custom upload destination, buffering strategy, or file-writing recipe.
Keep the output and lifecycle clear
- Use a path with an
.mp4extension when following the documented file example. - Call
stop()once the actions to capture are complete. - Wait for
stop()to resolve before closing the browser. - Ensure the destination directory exists and the Node.js process can write there.
- Do not assume that options or defaults from the older
page.screencast()API also apply topage.record().
3. Choose the right kind of browser capture
Several Chrome and Puppeteer features involve the screen, but they produce different results:
| Need | Use | Output |
|---|---|---|
| Save page activity as a video | Puppeteer page.record() |
MP4 video stream; the documented example writes to a path |
| Receive individual screen frames | Chrome DevTools Protocol Page.startScreencast and Page.stopScreencast |
Frame-oriented screencast data, a different protocol workflow |
| Record browser steps to replay or export | Chrome DevTools Recorder | A user-flow artifact, such as JSON or a Puppeteer script, not a page video |
Chrome DevTools Protocol documents frame-oriented screencasting separately from its screen-recording commands; see the Page domain protocol reference. Chrome DevTools Recorder is for recording and replaying user flows; see Chrome’s Recorder documentation.
What about page.screencast()?
Puppeteer’s current repository documentation marks Page.screencast() obsolete and directs users to Page.record(). The older method’s documentation describes WebM output, VP9 at 30 FPS by default, an ffmpeg requirement, and Chrome 153+ compatibility. Those are details of the older API; do not treat them as defaults or requirements for page.record(). If a project is pinned to a particular Puppeteer release, check that release’s matching API reference before changing its capture code. See the Puppeteer Page.screencast() reference.
4. Version and configuration considerations
The API reference establishes the page.record() method, an MP4 video stream, and the path-based example. It does not, in the reviewed material, enumerate every RecordOptions field, state every platform limitation, define an exact minimum Chrome version, or establish audio support. These details can depend on the installed Puppeteer and browser versions.
- Check the Puppeteer version in your lockfile or with
npm ls puppeteer. - Use the API reference matching that version, rather than assuming the current main-branch docs describe an older installation.
- Confirm which browser Puppeteer launches in your environment and consult its matching protocol support.
- Try a short recording in the same operating environment before relying on it in a longer automation job.
Do not infer audio recording or configurable frame rate, codec, or resolution for page.record() from the older screencast API or merely from fields present in the DevTools protocol.
5. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
page.record is not a function |
The installed Puppeteer version may not expose the method, or the project is using a different package or version than expected. | Check npm ls puppeteer, confirm the imported package, and consult that release’s API documentation. Upgrade only after checking your project’s compatibility requirements. |
| The output file is missing | The recording may not have been stopped, the destination directory may not exist, or the process may lack write permission. | Await recording.stop(), use a valid writable path, and check that the code reached the stop call before browser closure. |
| The video is shorter than expected | Recording started after some page actions or stopped before the last action finished. | Start recording before the interactions you need and await navigation, animations, or other relevant work before stopping. |
| The video shows a loading or incomplete page | Navigation completion does not necessarily mean the specific content you need has rendered. | Wait for a meaningful selector or application state before starting the interactions or ending the recording. Choose a navigation condition appropriate to the site. |
| The recording stops when an action errors | An exception interrupted the normal flow. | Put await recording.stop() in a finally block and close the browser in an outer finally, as in the example. |
| An old tutorial requires ffmpeg or produces WebM | It may be describing the obsolete page.screencast() API rather than page.record(). |
For page video, check whether your installed Puppeteer supports page.record() and follow its matching documentation. Keep frame capture or legacy workflows separate. |
6. Performance, reliability, and cost
Performance
Recording adds work to a browser automation run and produces video data. Keep recordings to the interval that answers your debugging or documentation question. Avoid adding arbitrary long sleeps: wait for the actual selector or state you need, then stop as soon as the captured action sequence is complete.
Reliability
- Use
try/finallyaround both the recording lifecycle and the browser lifecycle. - Use explicit waits for page states that matter to the capture.
- Check that the output location is writable and has enough storage for your job.
- Validate a short output in your target environment, especially when Puppeteer or Chrome versions differ between development and deployment.
Cost
The documented Puppeteer workflow uses your own browser automation environment; the cited API documentation does not specify a per-recording service price. Account for the compute time and storage used by your environment. For a one-time local debugging clip, Puppeteer may be all you need. If the goal is a website screenshot rather than a video of interactions, a screenshot API can avoid managing a browser capture workflow.
7. Or skip the browser setup
If you only need a still image of a page, ScreenshotNeo provides a website screenshot API and MCP server. Its API returns a screenshot or PDF from one GET request. See the ScreenshotNeo API documentation for options and configuration.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses report the page verdict and billing status in headers. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
8. Frequently asked questions
Does Puppeteer save a recording automatically?
The documented example provides a path in page.record({ path: ... }) and then stops the recording. Follow that lifecycle and verify the output path in your run environment.
Is this the same as recording a Puppeteer script?
No. A page recording is video output. Chrome DevTools Recorder captures a user flow for replay or export as an automation artifact.
Can I use this to get a screenshot instead of a video?
For a still image, use Puppeteer’s screenshot API or a screenshot service. page.record() is intended for page video.
Does the recording include audio?
The reviewed Puppeteer API material does not establish audio support. Check the documentation and protocol versions that match your installed Puppeteer and browser; do not assume audio is included.


