This is an up-to-date guide on running Chromium in Vercel serverless functions in 2022. What you will read below is the result of two days of research, debugging, 100+ failed deployments, and a little bit of stress.
Use chrome-aws-lambda that comes with Chromium pre-configured to run in serverless, and puppeteer-core
due to the smaller size of Chromium distributive.
Turns out, choosing the right versions of dependencies is crucial. Newer versions of puppeteer-core
ship larger Chromium distributive, which will exceed the 50MB function size limit on Vercel.
{
"chrome-aws-lambda": "10.1.0",
// Install v10 to have a smaller Chromium distributive.
"puppeteer-core": "10.1.0"
}
If you feel adventerous and wish to update dependencies, start from updating
chrome-aws-lambda
. Its peer dependency onpuppeteer-core
will tell you the maximum supported version to use.
Playwright comes with a larger Chromimum instance that would exceed the maximum allowed serverless function size limit of 50MB on Vercel (transitively, AWS).
The way you write your function does not matter: it may be a Node.js function, a part of your Next.js /api
routes, or a Remix application. What matters on this stage is to launch Puppeteer with correct options.
// api/run.js
import edgeChromium from 'chrome-aws-lambda'
// Importing Puppeteer core as default otherwise
// it won't function correctly with "launch()"
import puppeteer from 'puppeteer-core'
// You may want to change this if you're developing
// on a platform different from macOS.
// See https://github.com/vercel/og-image for a more resilient
// system-agnostic options for Puppeteeer.
const LOCAL_CHROME_EXECUTABLE = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
export default async function (req, res) {
// Edge executable will return an empty string locally.
const executablePath = await edgeChromium.executablePath || LOCAL_CHROME_EXECUTABLE
const browser = await puppeteer.launch({
executablePath,
args: edgeChromium.args,
headless: false,
})
const page = await browser.newPage()
await page.goto('https://github.com')
res.send('hello')
}
puppeteer-core@10
doesn't work well with newer versions of Node.js. The pinned version should be Node.js 14.
- Go to your Vercel project.
- Go to "Settings", then "General".
- Locate the "Node.js version" section.
- Select "Node 14".
In addition to configuring this on Vercel, make sure that your project's package.json
doesn't have the engines.node
property that would contradict your choise:
{
"engines": {
// If you have a newer version of Node in your package.json
// Vercel will respect that and disregard what you've set
// in your project's settings.
"node": "14.x"
}
}
Basically, you should not see this warning in your deployment logs:
Warning: Detected "engines": { "node": ">=14" } in your `package.json` that will automatically upgrade when a new major Node.js Version is released. Learn More: http://vercel.link/node-version
If you do, this means your Node.js version is not configured correctly and you should repeat this section.
- https://github.com/vercel/og-image, an old example of how Vercel used Chromium on the server to generate OG images.
- vercel/community#124, a large discussion on Puppeteer/Playwright in serverless functions.
Error: The Serverless Function "XYZ" is XX.YYmb which exceeds the maximum size limit of 50mb. Learn More: https://vercel.link/serverless-function-size
This means you're deploying a Chromium executable that's too large. Solve this by Installing the right dependency versions.
Error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory
This error means you're running an older/newer version of Node.js rather than Node.js 14. Solve this by Using the right Node.js version.
People on the web will suggest all sorts of things to tackle this, like installing
libnss3.so
manually, but fret not: it's solved by using the right version of Node.js.
If you found this helpful, consider Buying me a cup of coffee.
This works perfectly 👍. Thank you for sharing this approach.