Installing netlify-cli on macOS Ventura with npm ci

Published:
February 10, 2023

If you’re like me, you love npm ci. A lot. Until that one fateful day.

Let’s say you want to install the Netlify CLI locally in order to automate your deployment without building on Netlify directly. My use case for this is using Hakyll, which in turn relies on Stack and Haskell, and Netlify does not seem to support this build path out of the box.

Because you don’t just want to follow the instructions written in the Netlify documentation and install an NPM package globally using

npm install -g netlify-cli

you try to install it locally and call the individual Netlify CLI sub commands using npm run.

So, you run

npm install --save netlify-cli

and it appears to work, at first.

We look at the size of the resulting node_modules folder and get nervous.

~/p/test-netlify-cli$du --si -s node_modules
432M    node_modules

Wow, so much needed to push some files to a server. Accepting this, we try to establish whether this can be reinstalled easily using npm ci (clean install), which is where we hit a road block.

~/p/test-netlify-cli$npm ci
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for @esbuild/android-arm@0.16.17: wanted {"os":"android","arch":"arm"} (current: {"os":"darwin","arch":"arm64"})
npm ERR! notsup Valid OS:    android
npm ERR! notsup Valid Arch:  arm
npm ERR! notsup Actual OS:   darwin
npm ERR! notsup Actual Arch: arm64

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/justusperlwitz/.npm/_logs/2023-02-10T04_46_03_996Z-debug-0.log

Ouch! What is this? android-arm? But we are building on macOS with arm64, why would it try to pull in android dependencies? We consult the internet, and find that people have related problems to this. First, we see that the problem seems not to lie in the Netlify CLI itself, but in esbuild. So we find one closed issue and another closed issue, both gone stale and not translated into any action.

Further searching reveals a post by Sean McPherson, talking about a seemingly related issue, during an automated build. In it, the author describes deleting package-lock.json and not committing it to version control as a workaround, and explains that this will not work well in a professional environment with multiple contributors.

Sadly, I am the only one working on my personal website, so luckily I can attempt to fix it by … deleting the package-lock.json file before I perform an npm install (and not clean install, since there is no lock file).

I will not do that of course, because I have too much pride and putting a lock file out of version control is exactly what I was warned about 1 month into starting as a Ruby on Rails developer at the start of my career more than 10 years ago.

And since some habits are just hard to break, I begun to dig a bit more into what is causing the issue specifically. When I read Sean McPherson’s blog post one more time, I see the build log mentioning a --no-optional flag. That lead me to believe that I can somehow nudge NPM into leaving out the Android related packages.

Just running

npm install --save --no-optional netlify-cli

does absolutely nothing differently (still have to delete the lock file every time), but it does show us an interesting hint:

npm WARN config optional Use `--omit=optional` to exclude optional dependencies, or
npm WARN config `--include=optional` to include them.
npm WARN config
npm WARN config     Default value does install optional deps unless otherwise omitted.

We attempt to follow the suggestion here and receive an even more interesting result:

~/p/test-netlify-cli$npm install --save --omit=optional netlify-cli
npm ERR! code 1
npm ERR! path ...
npm ERR! command failed
npm ERR! command sh -c node install.js
npm ERR! [esbuild] Failed to find package "@netlify/esbuild-darwin-arm64" on the file system
npm ERR!
npm ERR! This can happen if you use the "--no-optional" flag. The "optionalDependencies"
npm ERR! package.json feature is used by esbuild to install the correct binary executable
npm ERR! for your current platform. This install script will now attempt to work around
npm ERR! this. If that fails, you need to remove the "--no-optional" flag to use esbuild.

It looks like esbuild and/or netlify-cli are very keen on installing the relevant system packages. Unfortunately, I have not been able to figure out how to omit all the non-relevant packages, and just install @netlify/esbuild-darwin-arm64 directly. One way or another it breaks after trying to recreate node_modules or package-lock.json. For example, the following will not work:

npm install --save --omit=optional netlify-cli @netlify/esbuild-darwin-arm64

Maybe that is a limitation of NPM as well. As it stands right now, I have to run npm i instead of npm ci and one way or another other people seem to have this issue too.

I would be thrilled to hear from you! Please share your thoughts and ideas with me via email.

Back to Index