Skip to main content

Browser Types

Playwright supports three browser engines out of the box:

Chromium

Google Chrome and Microsoft Edge

Firefox

Mozilla Firefox

WebKit

Apple Safari

Launching Browsers

Basic Launch

const { chromium, firefox, webkit } = require('playwright');

// Launch Chromium
const browser = await chromium.launch();

// Launch Firefox
const browser = await firefox.launch();

// Launch WebKit
const browser = await webkit.launch();

Launch Options

const browser = await chromium.launch({
  headless: false,           // Run in headed mode
  slowMo: 100,              // Slow down by 100ms
  devtools: true,           // Open DevTools
  args: ['--start-maximized'],  // Browser arguments
  executablePath: '/path/to/chrome'  // Custom browser binary
});
From server/browserType.ts:66, the launch() method validates options and manages the browser process lifecycle.

Browser Class

The Browser class (client/browser.ts:31) represents a running browser instance:
export class Browser extends ChannelOwner<channels.BrowserChannel> {
  readonly _contexts = new Set<BrowserContext>();
  private _isConnected = true;
  readonly _name: string;
  
  async newContext(options: BrowserContextOptions = {}): Promise<BrowserContext> {
    // Creates isolated browser context
  }
  
  async newPage(options: BrowserContextOptions = {}): Promise<Page> {
    // Shortcut: creates context + page
  }
  
  contexts(): BrowserContext[] {
    return [...this._contexts];
  }
  
  version(): string {
    return this._initializer.version;
  }
  
  async close(): Promise<void> {
    // Closes browser and all contexts
  }
}

Browser Lifecycle

1

Launch

Browser process starts
const browser = await chromium.launch();
2

Create Contexts

Multiple isolated sessions
const context1 = await browser.newContext();
const context2 = await browser.newContext();
3

Use Browser

Perform automation tasks
4

Close

Clean up resources
await browser.close();

Browser Connection State

// Check if browser is connected
if (browser.isConnected()) {
  console.log('Browser is running');
}

// Listen for disconnection
browser.on('disconnected', () => {
  console.log('Browser closed');
});
From client/browser.ts:147-194:
isConnected(): boolean {
  return this._isConnected;
}

_didClose() {
  this._isConnected = false;
  this.emit(Events.Browser.Disconnected, this);
}

Browser Properties

Version Information

const version = browser.version();
console.log(`Browser version: ${version}`);

Browser Type

const browserType = browser.browserType();
console.log(`Browser name: ${browserType.name()}`);

Multiple Contexts Pattern

Browsers can host multiple independent contexts, which is much more efficient than launching multiple browsers:
const browser = await chromium.launch();

// User 1 session
const context1 = await browser.newContext({
  viewport: { width: 1920, height: 1080 },
  userAgent: 'Custom User Agent 1'
});

// User 2 session (completely isolated)
const context2 = await browser.newContext({
  viewport: { width: 1280, height: 720 },
  userAgent: 'Custom User Agent 2'
});

// Contexts don't share cookies, storage, or cache
await Promise.all([
  context1.newPage().then(page => page.goto('https://example.com')),
  context2.newPage().then(page => page.goto('https://example.com'))
]);
Always close browsers to prevent resource leaks. Unclosed browsers continue running in the background.

Persistent Context

Launch a browser with persistent storage (user data directory):
const context = await chromium.launchPersistentContext('./user-data', {
  headless: false,
  viewport: { width: 1280, height: 720 }
});

// This context persists cookies, localStorage, etc.
const page = await context.newPage();
await page.goto('https://example.com');

// Login state is saved for next time
await context.close();
From server/browserType.ts:74:
async launchPersistentContext(
  progress: Progress,
  userDataDir: string,
  options: BrowserTypeLaunchPersistentContextOptions
): Promise<BrowserContext>

Remote Browser Connection

Connect to a browser running on another machine:
const browser = await chromium.connect({
  wsEndpoint: 'ws://remote-server:3000'
});

// Use as normal
const context = await browser.newContext();
const page = await context.newPage();

Browser Server

Start a browser server for remote connections:
const browserServer = await chromium.launchServer({
  port: 3000
});

console.log(`Connect to: ${browserServer.wsEndpoint()}`);

// Remote clients can now connect
// ...

await browserServer.close();

CDP Session (Chromium Only)

Access Chrome DevTools Protocol directly:
const browser = await chromium.launch();

// Browser-level CDP session
const cdpSession = await browser.newBrowserCDPSession();

// Send CDP commands
await cdpSession.send('Performance.enable');
const metrics = await cdpSession.send('Performance.getMetrics');

await cdpSession.detach();
From client/browser.ts:151:
async newBrowserCDPSession(): Promise<api.CDPSession> {
  return CDPSession.from((await this._channel.newBrowserCDPSession()).session);
}

Error Handling

try {
  const browser = await chromium.launch({
    executablePath: '/invalid/path'
  });
} catch (error) {
  if (error.message.includes('Failed to launch')) {
    console.error('Browser failed to start');
  }
}

Browser Process Management

Playwright automatically manages browser processes:
  1. Process Launch - Starts browser with appropriate flags
  2. Connection Setup - Establishes WebSocket or pipe communication
  3. Protocol Initialization - Sets up CDP/Juggler/Inspector protocol
  4. Context Management - Tracks all browser contexts
  5. Cleanup - Terminates browser process on close
From server/browserType.ts, the browser launch flow includes:
  • Option validation
  • Executable path resolution
  • Process spawning
  • Connection establishment
  • Protocol handshake

Best Practices

Launch once, create multiple contexts. Contexts are lightweight.
// Good
const browser = await chromium.launch();
for (let i = 0; i < 10; i++) {
  const context = await browser.newContext();
  // ... test ...
  await context.close();
}
await browser.close();
Use try-finally or async disposal to ensure cleanup.
const browser = await chromium.launch();
try {
  // ... use browser ...
} finally {
  await browser.close();
}
Listen for disconnection events.
browser.on('disconnected', () => {
  console.log('Browser crashed or was closed');
});

Browser Arguments

Customize browser behavior with command-line arguments:
const browser = await chromium.launch({
  args: [
    '--disable-web-security',
    '--disable-features=IsolateOrigins,site-per-process',
    '--no-sandbox',
    '--disable-setuid-sandbox'
  ]
});
Disabling security features is dangerous. Only use in controlled test environments.

Next Steps

Browser Contexts

Learn about isolated browser sessions

Pages and Frames

Working with tabs and iframes

Test Isolation

Ensuring test independence

Build docs developers (and LLMs) love