How to Close a Puppeteer BrowserContext
Close a Puppeteer context with `await context.close()`. Learn what it closes, how it differs from browser shutdown, and how to handle cleanup safely.
To close a Puppeteer browser context and all pages associated with it, call and await context.close():
await context.close();
The method returns a Promise<void>. The default browser context cannot be closed. Use a separately created context when you need a context you can dispose of independently. See Puppeteer’s BrowserContext.close() reference.
Close a separately created context
Create the context, open pages within it, perform your work, then close the context when that work is finished. Closing the context also closes its associated pages, so you do not need to close each page first if your goal is to dispose of the entire context.
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch();
const context = await browser.createBrowserContext();
try {
const page = await context.newPage();
await page.goto('https://example.com');
console.log(await page.title());
} finally {
await context.close();
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
The finally block ensures cleanup is attempted even if page navigation or other work throws. The example closes both the context and the browser because it launched the browser for this script and is finished with the whole process. If you plan to reuse the browser, close only the context.
A new browser context has isolated cookies and local storage relative to other contexts; Puppeteer’s context creation documentation also says contexts do not share cookies or cache. That makes a separately created context useful for isolating a task whose state should be discarded afterward. See BrowserContext and BrowserContext context details.
Choose the right cleanup operation
| Call | Effect | Use it when |
|---|---|---|
await context.close() |
Closes that context and its associated pages. | You are done with one isolated context but may keep the browser running. |
await browser.close() |
Closes the browser and all associated pages. | You are done with the browser process and its work. |
await browser.disconnect() |
Disconnects Puppeteer while leaving the browser process running. | You want to detach the client while preserving the browser process. |
These methods have different scopes. Choose based on whether you want to end one context, shut down the browser, or detach Puppeteer. Refer to Puppeteer’s Browser.close() and Browser.disconnect() references.
Common mistakes and troubleshooting
- Trying to close the default context: Puppeteer does not allow the default browser context to be closed. Create a separate context with
browser.createBrowserContext()when you need independently disposable context state. - Expecting pages to stay open: Closing a context closes its associated pages. If you intend to keep other pages alive, close only the specific page you are done with and retain the context.
- Using
browser.close()for one task: This shuts down the browser and all its pages. Usecontext.close()if the browser should continue serving other work. - Calling
browser.disconnect()and expecting shutdown: Disconnecting Puppeteer leaves the browser process running. Callbrowser.close()when the process should end. - Cleanup is skipped after an error: Put context cleanup in a
finallyblock so it runs after success or failure. Await the close call so the script observes its completion. - Context creation or cleanup behaves differently in your environment: Check the API supported by the Puppeteer package installed in your project. The referenced documentation pages report different API versions, so do not assume every page describes one identical release.
Reliability and lifecycle guidance
- Create a separate context for work that needs its own cookies and local storage.
- Keep page work inside a
tryblock. - In
finally, awaitcontext.close()to dispose of the context and its pages. - Close the browser as well only when your code owns its lifecycle and no other work needs it.
Context cleanup is scoped to the context. It is not a replacement for shutting down a browser process that your program launched and no longer needs.
Or skip the browser setup
If your task is simply to capture a webpage, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call API returns a screenshot or PDF, without requiring you to launch and clean up a Puppeteer browser for each capture.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does context.close() close every page?
It closes all pages associated with that context.
Does it close the browser?
No. It closes the context. Use browser.close() to close the browser and its pages.
Can I close the default browser context?
No. Create a separate context if it needs to be independently closed.
Do I need to close each page before closing the context?
No, not when your intent is to close the whole context. Closing individual pages is useful when you want the context and its other pages to remain open.


