Installing Playwright solves two tasks at once: it sets up the test runner and brings in the browser engines it drives. This is important to grasp from the start, because the package and the browsers are different entities with different lifecycles. The runner is an ordinary npm dependency, while Chromium, Firefox and WebKit are separate binaries that Playwright downloads and keeps in its own cache, not in the project's node_modules.
The recommended path is the official generator, npm init playwright@latest. It does not merely install the package: it asks a few questions and unfolds a ready structure. For a TypeScript project the sensible answers are to put tests in the e2e directory, add a GitHub Actions workflow and install the browsers right away. The result is a working playwright.config.ts, an example test and a configured CI to build on rather than assembling everything by hand.
When the project already exists and only the runner is needed, installation is manual and just as short. The @playwright/test package is installed as a dev dependency, and the browsers are brought in by a separate command, npx playwright install. The split is not accidental: updating the npm package and updating the engines are two different actions, and Playwright deliberately does not pull hundreds of megabytes of binaries through the ordinary npm graph.
In a Linux CI environment the binaries alone are not enough: browsers need system libraries - fonts, graphics and audio dependencies. For this there is npx playwright install --with-deps: it installs both the browsers and their system dependencies in one command. This is a standard step in a CI pipeline; without it a browser on a clean ubuntu machine simply will not start, and the tests will fail before the first scenario.
The key operational rule is to keep the package version and the browser version consistent. The binaries are versioned together with the runner: a specific version of @playwright/test corresponds to a specific set of browsers. So after updating the package you immediately run install with the same version - otherwise the tests will run on engines the runner is not designed for, and behavior will start to diverge from what is expected.
It helps to pin down both commands once - the generator for a new project and the manual install for an existing one - so you do not recall them each time. Below are both variants plus the step for Linux CI; you return to this map when setting up a new environment or fixing a broken installation.
A separate topic is what must not end up in the repository. The browser cache is hundreds of megabytes of platform-bound binaries; committing it is pointless and harmful, it bloats history and does not transfer between operating systems anyway. Browsers are installed from a clean state on each machine with the install command, and in CI they are cached by the CI's own means, not through git.
The typical installation failures are predictable. Forgetting --with-deps in Linux CI gives a browser startup failure out of nowhere that looks like a mysterious test error. Updating @playwright/test but not the browsers means catching behavior divergences between local and CI. And committing the browser cache bloats the repository with binaries that will have to be reinstalled anyway. Install the package and the browsers consistently and keep the cache out of git.
# Recommended generator for a new project
npm init playwright@latest
# Answers for a TypeScript project:
# Where to put tests? e2e
# Add GitHub Actions? yes
# Install browsers? yes# Manual install into an existing project
npm i -D @playwright/test
npx playwright install
# Linux CI - browsers plus system dependencies
npx playwright install --with-deps