ScreenshotNeo

BlogGuides

Puppeteer Screen Recording Options Explained

Use Puppeteer's experimental page.record() for MP4 recording. Compare it with obsolete page.screencast(), learn the lifecycle, and choose the right capture method.

By the ScreenshotNeo team4 October 20268 min read

For a new Puppeteer browser-page recording, use page.record(): the current API reference describes it as experimental and says it produces an MP4 stream using Chrome DevTools Protocol’s Page.startScreenRecording. Start the recording, perform the page actions you want to capture, then call stop(). Treat page.screencast() as a legacy API: Puppeteer’s reference calls it obsolete and points to page.record().

Use page.screenshot() when you need a still image rather than video. The choice is therefore about the deliverable: MP4 recording, legacy WebM screencast, or a static image.

1. Choose the right Puppeteer capture method

Method Status in the cited reference Output and documented behavior Use it for
page.record(options) Experimental MP4 video stream; uses Chrome DevTools Protocol Page.startScreenRecording. New recordings when experimental API status is acceptable.
page.screencast(options) Obsolete; reference directs users to record() WebM with VP9 at 30 FPS by default. The reference specifies Chrome 153+ and says ffmpeg must be installed. Maintaining existing screencast code while planning a move to record().
page.screenshot(options) Still-image API Image output; documented options include output path, image type, and full-page capture. Single-frame evidence, thumbnails, or page snapshots.

The Chrome 153+ requirement and ffmpeg note above are specifically documented for screencast(). Do not assume they apply to record(). The surfaced record() reference does not state a minimum Chrome version or an ffmpeg dependency. Check the API docs for the exact Puppeteer version and browser you deploy.

Sources: Puppeteer Page.record(), Page.screencast(), Page API, and Page.screenshot().

2. Record a page to MP4 with page.record()

This complete Node.js example launches Puppeteer, opens a page, starts recording to a file, performs page activity, stops the recording, and closes the browser even if an operation fails. Install Puppeteer in your project with npm install puppeteer. The example uses the documented {path: 'recording.mp4'} option and recorder stop() method; verify availability against your installed version because the API is experimental.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

    const recorder = await page.record({ path: 'recording.mp4' });
    try {
      // Do the actions you want the video to show.
      await page.waitForTimeout(1000);
      await page.reload({ waitUntil: 'domcontentloaded' });
      await page.waitForTimeout(1000);
    } finally {
      await recorder.stop();
    }
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

The recorder is documented as a ReadableStream<Uint8Array>, and the official example demonstrates a path option followed by await recorder.stop(). If you use the path option, the example writes the recording to that path. When consuming the stream yourself, use the stream interface provided by the Puppeteer version in your project and confirm whether it is already being written to a file; avoid writing the same bytes twice.

Recording lifecycle

  1. Navigate to the page and prepare its initial state.
  2. Start the recorder with await page.record(options).
  3. Perform the interactions or wait for the page state you want in the video.
  4. Always call await recorder.stop() to finish the recording.
  5. Close the browser after the recorder has stopped.

Stopping in a finally block helps avoid leaving a recording unfinished if page work throws. If navigation or a page action fails, preserve the original error while still attempting to stop the recorder and close the browser.

3. Maintain legacy page.screencast() code

Puppeteer’s reference says Page.screencast() is obsolete and points to Page.record(). If you have a temporary reason to keep it, the documented usage pattern is similar, but its format and requirements differ.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

    const recorder = await page.screencast({ path: 'recording.webm' });
    try {
      await page.waitForTimeout(2000);
    } finally {
      await recorder.stop();
    }
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

The screencast reference documents WebM with VP9 at 30 FPS by default, Chrome 153+, and an ffmpeg installation requirement. Those details describe the documented screencast() method; they are not settings or requirements to transfer to record(). Since the method is marked obsolete, use it only where an existing dependency requires it and plan to verify a migration.

4. Options and version compatibility

Both recording methods accept an optional options object, but the available research does not expose complete RecordOptions or ScreencastOptions field tables. The safe documented example for record() uses {path: 'recording.mp4'}; the screencast example uses a path ending in .webm. Do not rely on unverified options for bitrate, dimensions, quality, duration, or frame-rate overrides.

Puppeteer documentation is versioned. A next reference can describe behavior newer than a stable release, and browser compatibility can depend on the Puppeteer and Chrome versions you actually run. Before shipping:

  • Check whether your installed Puppeteer version exposes page.record().
  • Check the matching API reference for accepted option fields and output behavior.
  • For legacy screencast(), confirm the documented Chrome 153+ requirement and ffmpeg availability in the runtime environment.
  • Run a short capture in the same deployment image and browser build used in production.

Sources: record reference, screencast reference.

5. Save a screenshot instead of recording video

A screenshot captures a still frame. Puppeteer’s screenshot method has image options such as path, type, and fullPage; it does not record motion.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });
    await page.screenshot({ path: 'page.png', type: 'png', fullPage: true });
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Choose this path for a static artifact. Choose a recording API when the sequence of page states matters.

6. Or skip the browser setup

If you need a still screenshot rather than a video, ScreenshotNeo is a website screenshot API and MCP server. Its API accepts one GET request and returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation.

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}`);

These calls produce still images or a PDF, not a screen recording. ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, and cache hits are not billed. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month with no card.

7. Troubleshooting

Symptom Likely cause What to do
page.record is not a function The installed Puppeteer version does not expose the experimental API, or the code is running against a different package/browser setup than expected. Check the installed Puppeteer version and its matching Page reference. Upgrade only after confirming the version and browser combination supports the method you need.
Recording does not finish or the file is incomplete stop() was skipped because page work threw, or the browser was closed before recording stopped. Call await recorder.stop() in a finally block, then close the browser.
Legacy screencast fails at startup The documented screencast path requires Chrome 153+ and ffmpeg. Verify the Chrome version and install ffmpeg in the environment if retaining this obsolete method. Consider moving to record() after checking its version-specific support.
Output format is not what the consumer expects record() documents MP4 output; screencast() documents WebM/VP9 defaults. Choose the API based on the required deliverable and validate the resulting file in the downstream system. Do not infer that changing a filename extension converts the encoding.
Code works against docs but not in deployment The docs may be for a newer or different Puppeteer/Chrome combination than the deployed one. Pin and inspect the deployed versions, consult the matching API reference, and capture a short sample in the deployment environment.
Still image produced when video was expected page.screenshot() captures one image, not motion. Use page.record() for the documented MP4 recording workflow, or maintain screencast() only for a compatibility need.

8. Performance, reliability, and cost considerations

The cited API references do not provide benchmarks, resource estimates, or a cost model for recording, so size capture jobs against your own page and runtime. Video captures can create larger artifacts than still screenshots; measure output size and processing time with representative pages before setting storage and job limits. Keep the recording interval focused on the interaction you need, stop promptly, and close the browser to release resources.

For reliable automation, wait for the page state your scenario actually requires before recording, and make cleanup unconditional. Network-idle waits can be unsuitable for pages with persistent requests; select a navigation condition that matches the page rather than waiting indefinitely. Treat recording as experimental where the API reference labels it that way, and validate after Puppeteer or Chrome upgrades.

Puppeteer is a browser automation library you run in your own environment, so account for the compute, storage, and maintenance of that environment. ScreenshotNeo offers hosted still-image and PDF capture rather than video: plans range from free 1,000 monthly shots to paid tiers, with $5 for 3,000 shots on Starter. Every feature is available on every plan; yearly billing gives two months free. Review the docs for API behavior and plan details before choosing it for still capture.

9. Frequently asked questions

How do I record a video with Puppeteer?

Start with await page.record({path: 'recording.mp4'}), do the page work to capture, and call await recorder.stop(). Confirm support in the reference for your installed version.

What is the difference between page.record() and page.screencast()?

The surfaced reference describes record() as experimental MP4 recording and screencast() as obsolete, with WebM/VP9 at 30 FPS by default. Screencast also has documented Chrome 153+ and ffmpeg requirements.

Does Puppeteer screen recording need ffmpeg?

The reviewed documentation states an ffmpeg requirement for screencast(). It does not state that requirement for record().

How do I save a Puppeteer recording as MP4?

Use the documented page.record({path: 'recording.mp4'}) pattern, then stop the returned recorder. Check the installed version’s reference because record() is experimental.

Can ScreenshotNeo record a browser session?

No. ScreenshotNeo captures still screenshots or PDFs. Use Puppeteer when the output must show motion over time.