Browserless
The headless Chrome/Chromium driver on top of Puppeteer. Take screenshots, generate PDFs, extract text and HTML with a production-ready API.
Install / Use
/learn @microlinkhq/BrowserlessREADME
The headless Chrome/Chromium driver on top of Puppeteer.
- Highlights
- Installation
- Usage
- The cloud API solution
- CLI
- Initializing a browser
- Built-in
- Extended
- Packages
- FAQ
- License
Highlights
- Compatible with Puppeteer API (text, screenshot, html, pdf).
- Built-in adblocker for canceling unnecessary requests.
- Shell interaction via Browserless CLI.
- Easy Google Lighthouse integration.
- Automatic retry & error handling.
- Sensible good defaults.
Installation
You can install it via npm:
npm install browserless puppeteer --save
Browserless runs on top of Puppeteer, so you need that installed to get started.
You can choose between puppeteer and puppeteer-core depending on your use case.
Usage
Here is a complete example showcasing some Browserless capabilities:
const createBrowser = require('browserless')
const termImg = require('term-img')
// First, create a browserless factory
// This is similar to opening a browser for the first time
const browser = createBrowser()
// Browser contexts are like browser tabs
// You can create as many as your resources can support
// Cookies/caches are limited to their respective browser contexts, just like browser tabs
const browserless = await browser.createContext()
// Perform your required browser actions.
// e.g., taking screenshots or fetching HTML markup
const buffer = await browserless.screenshot('http://example.com', {
device: 'iPhone 6'
})
console.log(termImg(buffer))
// After your task is done, destroy your browser context
await browserless.destroyContext()
// At the end, gracefully shutdown the browser process
await browser.close()
As you can see, Browserless uses a single browser process, allowing you to create and destroy multiple browser contexts within that same process.
If you're already using Puppeteer in your project, you can layer Browserless on top simply by installing it.
You can also include additional Browserless packages to suit your specific needs, all of which work well with Puppeteer.
The cloud API solution
If you don’t want to manage that infrastructure, you can use the fully managed Microlink API.
It covers every browserless use case but automatically handles proxy rotation, paywalls, bot detection, and restricted platforms such as major social networks, while scaling on demand.
Pricing is pay-as-you-go and starts for free.
CLI
Using the Browserless command-line tool, you can interact with Browserless through a terminal window, or use it as part of an automated process:
<div style="margin: auto;"> <video poster="/static/cli.png" loop="" controls="" src="https://github.com/microlinkhq/browserless/assets/2096101/5200b2c5-d930-40e7-b128-6d23a6974c28" style="width: 100%;border-radius: 4px;" autoplay=""></video> </div>Install @browserless/cli globally using your favorite package manager:
npm install -g @browserless/cli
Then run browserless in your terminal to see the list of available commands.
Initializing a browser
Initializing Browserless creates a headless browser instance.
const createBrowser = require('browserless')
const browser = createBrowser({
timeout: 25000,
lossyDeviceName: true,
ignoreHTTPSErrors: true
})
This instance provides several high-level methods.
For example:
// Call `createContext` to create a browser tab
const browserless = await browser.createContext({ retry: 2 })
const buffer = await browserless.screenshot('https://example.com')
// Call `destroyContext` to close the browser tab.
await browserless.destroyContext()
The browser keeps running until you explicitly close it:
// At the end, gracefully shutdown the browser process
await browser.close()
.constructor(options)
The createBrowser method supports puppeteer.launch#options.
Browserless provides additional options for creating a browser instance:
defaultDevice
Sets your browser viewport to that of the specified device:
type: string<br/>
default: 'Macbook Pro 13'
lossyDeviceName
type: boolean<br/>
default: false
Allows for a margin of error when setting the device name.
// Initialize browser instance
const browser = require('browserless')({ lossyDeviceName: true });
(async () => {
// Create context/tab
const tabInstance = await browser.createContext();
// Even if the device name is misspelled, the property will default to 'MacBook Pro'
console.log(tabInstance.getDevice({ device: 'MacBook Pro' }))
console.log(tabInstance.getDevice({ device: 'macbook pro 13' }))
console.log(tabInstance.getDevice({ device: 'MACBOOK PRO 13' }))
console.log(tabInstance.getDevice({ device: 'macbook pro' }))
console.log(tabInstance.getDevice({ device: 'macboo pro' }))
})()
The provided name will be resolved to closest matching device.
This comes in handy in situations where the device name is set by a third-party.
mode
type: string<br/>
default: launch<br/>
values: 'launch' | 'connect'
Specifies if the browser instance should be spawned using puppeteer.launch or puppeteer.connect.
timeout
type: number<br/>
default: 30000
Changes the default maximum navigation time.
puppeteer
type: Puppeteer<br/>
default: puppeteer|puppeteer-core|puppeteer-firefox
By default, it automatically detects which libary is installed (thus either puppeteer or puppeteer-core based on your installed dependecies.
.createContext(options)
After initializing the browser, you can create a browser context which is equivalent to opening a tab:
const browserless = await browser.createContext({
retry: 2
})
Each browser context is isolated, thus cookies/cache stay within its corresponding browser contexts, just like browser tabs. Each context can be initialized with its own set of options.
options
All of Puppeteer's browser.createBrowserContext#options are supported.
Browserless provides additional browser context options:
retry
type: number<br/>
default: 2
The number of retries that can be performed before considering a navigation as failed.
.browser()
Returns the internal Browser instance.
const headlessBrowser = await browser.browser()
console.log('My headless browser PID is', headlessBrowser.process().pid)
console.log('My headless browser version is', await headlessBrowser.version())
.respawn()
Respawns the internal browser.
const getPID = promise => (await promise).process().pid
console.log('Process PID:', await getPID(browser.browser()))
await browser.respawn()
console.log('Process PID:', await getPID(browser.browser()))
This method is an implementation detail, normally you don't need to call it.
.close()
Closes the internal browser.
const { onExit } = require('signal-exit')
// automatically teardown resources after
// `process.exit` is called
onExit(browser.close)
Built-in
.html(url, options)
Serializes the content of a target url into HTML.
const html = await browserles
Related Skills
imsg
334.1kiMessage/SMS CLI for listing chats, history, and sending messages via Messages.app.
node-connect
334.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
oracle
334.1kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
lobster
334.1kLobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (s
