Platform as a service / Render
Playwright on Render: an install step with nowhere to write
The build command runs the browser install, the build succeeds, and the running service cannot find the browser.
What is actually wrong
The install writes into a cache directory in the build user's home. Whether that directory survives into the running service depends on the deployment mode, and on a native runtime it does not. The build log says the browsers were installed, which is true and unhelpful.
What Render gives you to work with
either a native runtime built from your repository, or a container built from your Dockerfile.
- Packaging: no explicit size limit. The native runtime is the constraint instead: it gives you a language runtime and not a package manager, so system libraries cannot be added to it.
- Filesystem: writable and ephemeral unless a persistent disk is attached. A disk changes the deployment to a single instance, which matters if the render workload is what you were scaling.
- Processes: full control in a container service. The smaller instance sizes have well under a gigabyte of memory, which a browser exhausts on a large document.
The fix, if you are keeping Playwright
Set the browser path to a location inside the project directory so the install output is part of what gets deployed, or move to a Docker service where the install is a layer in the image. The second is the one that keeps working.
# Build command, if staying on a native runtime:
PLAYWRIGHT_BROWSERS_PATH=0 npm ci && npx playwright install chromium
# This puts the browser in node_modules so it deploys with the code.
# It does not install the system libraries the browser links against,
# which a native runtime still has no way to provide.What still hurts after that
Even with the browser in the right place, a native runtime cannot supply the system libraries, so this only ever gets you to the next error. The dependency installer needs root and there is none. Docker is the only configuration on this platform where a browser genuinely runs.
What Playwright is genuinely good at
a better API than Puppeteer for waiting on real page state, and a first-party dependency installer that knows which system packages the browser needs. That is worth keeping in view: the problem on this page is where it runs, not what it produces. Playwright is a browser automation library that installs its browsers outside node_modules, into a shared cache directory, at install time. It needs the same browser and shared libraries as Puppeteer, plus an install step that runs separately from the package install and writes to a location your deployment probably does not copy.
The other shape of the answer
Every fix above keeps the renderer inside your deployment, which means the constraint stays yours: the package size, the shared libraries, the fonts, the memory, the patching. The alternative is an HTTP call from Render to something that already has a browser in it, which turns all of the above into a request and a response. That is what this API is, and it is the reason these pages exist. Whether that trade is right depends on whether rendering is a thing you want to operate.
Frequently asked
Can Playwright run on Render at all?
Set the browser path to a location inside the project directory so the install output is part of what gets deployed, or move to a Docker service where the install is a layer in the image. The second is the one that keeps working. Whether that is worth doing is a separate question from whether it is possible, and the section above on what still hurts is the honest answer to it.
Why does it work locally?
Because a development machine has root, a package manager, several gigabytes of memory, a full font set and no packaging limit. Every one of those is a thing Render constrains. A renderer that works locally and fails on deploy has not regressed: it has met the first environment that does not give it everything.
Related failures
The same platform with a different renderer, and the same renderer on other platforms.
Puppeteer on Render: a native runtime with no package manager
On a native runtime service the browser fails to start with missing shared libraries and there is no way to install them.
Playwright on AWS Lambda: browsers that are not in your bundle
At runtime, not at deploy time: "Executable doesn't exist at /home/sbx_user1051/.cache/ms-playwright/chromium-.../chrome-linux/chrome".
Playwright on Vercel: an install step the build never runs
Deploy succeeds, first request fails with "Executable doesn't exist at ...ms-playwright/chromium-...".
Playwright on Google Cloud Run: a two gigabyte image on a cold start
Everything works, and the first request after a quiet period takes many seconds before any of your code runs.
Playwright on Docker: browsers downloaded outside the image layer
The image builds, and at runtime the browser is missing, or the container downloads it again on every start.
Every renderer, on every platform
The full grid, grouped by what kind of environment the platform is.
What goes wrong when HTML becomes a PDF
Once it deploys, the next set of problems is in the output rather than the infrastructure.
If the render moves off this platform, none of the above is your problem to keep solving. 100 free documents a month, and a playground that needs no signup.