Fix installing the Node.js canvas package on macOS
By Flavio Copes
Learn how to fix the node-pre-gyp build error when installing the Node.js canvas package on macOS by brew installing cairo, pango and the other dependencies.
I wanted to use the Node.js canvas NPM package but running npm install canvas failed with messages like this:
npm ERR! code 1
npm ERR! path /Users/flaviocopes/dev/old/generate-images-posts/node_modules/canvas
npm ERR! command failed
npm ERR! command sh -c node-pre-gyp install --fallback-to-build
npm ERR! Failed to execute '/opt/homebrew/Cellar/node@16/16.14.2/bin/node /opt/homebrew/Cellar/node@16/16.14.2/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/Users/flaviocopes/dev/old/generate-images-posts/node_modules/canvas/build/Release/canvas.node --module_name=canvas --module_path=/Users/flaviocopes/dev/old/generate-images-posts/node_modules/canvas/build/Release --napi_version=8 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v93' (1)
npm ERR! node-pre-gyp info it worked if it ends with ok
npm ERR! node-pre-gyp info using node-pre-gyp@0.11.0
npm ERR! node-pre-gyp info using node@16.14.2 | darwin | arm64
npm ERR! node-pre-gyp WARN Using request for node-pre-gyp https download
npm ERR! node-pre-gyp info check checked for "/Users/flaviocopes/dev/old/generate-images-posts/node_modules/canvas/build/Release/canvas.node" (not found)
npm ERR! node-pre-gyp http GET https://github.com/node-gfx/node-canvas-prebuilt/releases/download/v2.6.1/canvas-v2.6.1-node-v93-darwin-unknown-arm64.tar.gz
npm ERR! node-pre-gyp http 404 https://github.com/node-gfx/node-canvas-prebuilt/releases/download/v2.6.1/canvas-v2.6.1-node-v93-darwin-unknown-arm64.tar.gz
npm ERR! node-pre-gyp WARN Tried to download(404): https://github.com/node-gfx/node-canvas-prebuilt/releases/download/v2.6.1/canvas-v2.6.1-node-v93-darwin-unknown-arm64.tar.gz
npm ERR! node-pre-gyp WARN Pre-built binaries not found for canvas@2.6.1 and node@16.14.2 (node-v93 ABI, unknown) (falling back to source compile with node-gyp)
npm ERR! node-pre-gyp http 404 status code downloading tarball https://github.com/node-gfx/node-canvas-prebuilt/releases/download/v2.6.1/canvas-v2.6.1-node-v93-darwin-unknown-arm64.tar.gz
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@8.4.1
npm ERR! gyp info using node@16.14.2 | darwin | arm64
To fix this, I ran:
brew install pkg-config cairo pango libpng jpeg giflib librsvg
and npm install canvas worked fine!
The canvas README now lists two more Homebrew packages for macOS, pixman and python-setuptools. This is the full command it gives today:
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman python-setuptools
Why this happens
canvas isn’t pure JavaScript. It’s a native module that draws images using Cairo, a C graphics library. So installing it means compiling C code that links against Cairo and a few related libraries.
To save you that compile step, the package first tries to download a prebuilt binary. That’s the node-pre-gyp http GET line in the log. When no prebuilt binary matches your exact combination of Node version, platform, and CPU, that download 404s. canvas 2 never published a darwin-arm64 build for Apple Silicon Macs, and that’s the 404 you see above.
At that point node-pre-gyp falls back to building from source with node-gyp. And that only works if the C libraries it needs are already on your machine. They aren’t by default, so the build fails.
The brew install line installs those libraries. Cairo and Pango handle drawing and text, libpng, jpeg and giflib handle image formats, librsvg handles SVG, and pkg-config lets the build find them all.
The two extra packages in the README’s list are pixman, the low-level pixel library Cairo uses, and python-setuptools, for the Python scripts node-gyp runs during the build. JPEG, GIF and SVG support are optional, so you can skip jpeg, giflib and librsvg if you don’t need those formats.
Do you still need this with canvas 3?
The log above comes from canvas 2. It downloaded prebuilt binaries with node-pre-gyp, and it needed a separate binary for every Node version, platform and CPU. A new Node release or a new Mac could easily hit a 404.
canvas 3 needs Node 18.12 or later. Its prebuilt binaries use N-API, so one build works across Node versions. Prebuilds are published for macOS on Intel and Apple Silicon, for Windows x64, and for Linux with glibc on x64 (and on ARM64 since canvas 3.1.1).
So on a recent Mac, npm install canvas downloads a prebuild and doesn’t compile anything. You need the Homebrew libraries only when you build from source on purpose with npm install canvas --build-from-source, or when you’re on a platform with no prebuild, like Alpine Linux, which uses musl instead of glibc.
A variation of the same error
If Cairo is missing when the build starts, you’ll see a clearer message instead:
Package cairo was not found in the pkg-config search path.
It has the same root cause and the same fix. Run the brew install command, then run npm install again. Homebrew puts these libraries where pkg-config looks, the source compile finishes, and the install succeeds.
Want me to talk about your product? You can sponsor this site.
Related posts about js: