Register for this year’s #ChromeDevSummit happening on Nov. 11-12 in San Francisco to learn about the latest features and tools coming to the Web. Request an invite on the Chrome Dev Summit 2019 website

Getting Started with Headless Chrome

TL;DR

Headless Chrome
is shipping in Chrome 59. It's a way to run the Chrome browser in a headless environment.
Essentially, running
Chrome without chrome! It brings all modern web platform features provided
by Chromium and the Blink rendering engine to the command line.

Why is that useful?

A headless browser is a great tool for automated testing and server environments where you
don't need a visible UI shell. For example, you may want to run some tests against
a real web page, create a PDF of it, or just inspect how the browser renders an URL.

Note: Headless mode has been available on Mac and Linux since Chrome 59.
Windows support
came in Chrome 60.

Starting Headless (CLI)

The easiest way to get started with headless mode is to open the Chrome binary
from the command line. If you've got Chrome 59+ installed, start Chrome with the --headless flag:

Note: Right now, you'll also want to include the --disable-gpu flag if you're running
on Windows. See crbug.com/737678.

chrome should point to your installation of Chrome. The exact location will
vary from platform to platform. Since I'm on Mac, I created convenient aliases
for each version of Chrome that I have installed.

If you're on the stable channel of Chrome and cannot get the Beta, I recommend
using chrome-canary:

Running with --screenshot will produce a file named screenshot.png in the
current working directory. If you're looking for full page screenshots, things
are a tad more involved. There's a great blog
post from David Schnurr that has you covered. Check out
Using headless Chrome as an automated screenshot tool
.

REPL mode (read-eval-print loop)

The --repl flag runs Headless in a mode where you can evaluate JS expressions
in the browser, right from the command line:

Note: the addition of the --crash-dumps-dir flag when using repl mode.

Debugging Chrome without a browser UI?

When you run Chrome with --remote-debugging-port=9222, it starts an instance
with the DevTools protocol enabled. The
protocol is used to communicate with Chrome and drive the headless
browser instance. It's also what tools like Sublime, VS Code, and Node use for
remote debugging an application. #synergy

Since you don't have browser UI to see the page, navigate to http://localhost:9222
in another browser to check that everything is working. You'll see a list of
inspectable pages where you can click through and see what Headless is rendering:

DevTools remote debugging UI

From here, you can use the familiar DevTools features to inspect, debug, and tweak
the page as you normally would. If you're using Headless programmatically, this
page is also a powerful debugging tool for seeing all the raw DevTools protocol
commands going across the wire, communicating with the browser.

Using programmatically (Node)

Puppeteer

Puppeteer is a Node library
developed by the Chrome team. It provides a high-level API to control headless
(or full) Chrome. It's similar to other automated testing libraries like Phantom
and NightmareJS, but it only works with the latest versions of Chrome.

Among other things, Puppeteer can be used to easily take screenshots, create PDFs,
navigate pages, and fetch information about those pages. I recommend the library
if you want to quickly automate browser testing. It hides away the complexities
of the DevTools protocol and takes care of redundant tasks like launching a
debug instance of Chrome.

But things get tricky if you want a portable solution that works across multiple
platforms. Just look at that hard-coded path to Chrome :(

Using ChromeLauncher

Lighthouse is a marvelous
tool for testing the quality of your web apps. A robust module for launching
Chrome was developed within Lighthouse and is now extracted for standalone use.
The chrome-launcher NPM module
will find where
Chrome is installed, set up a debug instance, launch the browser, and kill it
when your program is done. Best part is that it works cross-platform thanks to
Node!

By default, chrome-launcher will try to launch Chrome Canary (if it's
installed), but you can change that to manually select which Chrome to use. To
use it, first install from npm:

Running this script doesn't do much, but you should see an instance of
Chrome fire up in the task manager that loaded about:blank. Remember, there
won't be any browser UI. We're headless.

To control the browser, we need the DevTools protocol!

Retrieving information about the page

Warning: The DevTools protocol can do a ton of interesting stuff, but it can be a bit
daunting at first. I recommend spending a bit of time browsing the
DevTools Protocol Viewer, first. Then, move on to the
chrome-remote-interface API docs to see how it wraps the raw protocol.

Using Selenium, WebDriver, and ChromeDriver

Right now, Selenium opens a full instance of Chrome. In other words, it's an
automated solution but not completely headless. However, Selenium can be
configured to run headless Chrome with a little work. I recommend
Running Selenium with Headless Chrome
if you want the
full instructions on how to set things up yourself, but I've dropped in some
examples below to get you started.

"The Headless Web" - Paul Kinlan's great blog
post on using Headless with api.ai.

FAQ

Do I need the --disable-gpu flag?

Only on Windows. Other platforms no longer require it. The --disable-gpu flag is a
temporary work around for a few bugs. You won't need this flag in future versions of
Chrome. See crbug.com/737678
for more information.

So I still need Xvfb?

No. Headless Chrome doesn't use a window so a display server like Xvfb is
no longer needed. You can happily run your automated tests without it.

What is Xvfb? Xvfb is an in-memory display server for Unix-like systems that enables you
to run graphical applications (like Chrome) without an attached physical display.
Many people use Xvfb to run earlier versions of Chrome to do "headless" testing.

Headless Chrome is similar to tools like PhantomJS. Both
can be used for automated testing in a headless environment. The main difference
between the two is that Phantom uses an older version of WebKit as its rendering
engine while Headless Chrome uses the latest version of Blink.