Reviving an old Electron app
Today I needed to use a personal project I'd built and last modified 5 years ago. I followed the readme and installed dependencies. As expected, it wasn't smooth.
MacOS
First I had to install grunt.
npm install -g grunt-cli
added 56 packages, and audited 57 packages in 3s
5 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 8.19.3 -> 10.9.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.2
npm notice Run npm install -g npm@10.9.2 to update!
Oh I can update npm? Let's do it
% npm install -g npm@10.9.2
npm ERR! code EBADENGINE
npm ERR! engine Unsupported engine
npm ERR! engine Not compatible with your version of node/npm: npm@10.9.2
npm ERR! notsup Not compatible with your version of node/npm: npm@10.9.2
npm ERR! notsup Required: {"node":"^18.17.0 || >=20.5.0"}
npm ERR! notsup Actual: {"npm":"8.19.3","node":"v16.17.0"}
Oh, I have node 16 and it requires at least node 18. Fine, let's skip for now and simply install dependencies.
So much red!
npm ERR! info sharp Downloading https://github.com/lovell/sharp-libvips/releases/download/v8.7.0/libvips-8.7.0-darwin-armv8.tar.gz
npm ERR! /Users/anhtuan/git/bestpick/phone/www/node_modules/sharp/install/libvips.js:81
npm ERR! throw new Error(`Status ${response.statusCode}`);
npm ERR! ^
npm ERR!
npm ERR! Error: Status 404
npm ERR! at /Users/anhtuan/git/bestpick/phone/www/node_modules/sharp/install/libvips.js:81:17
First it looks like it downloads some binary of sharp, and since it's an old version, it's not hosted by their CDN anymore.
Let's update the dependency
The next time I run npm i
, I get a similar error for electron.
npm ERR! code 1
npm ERR! path /Users/anhtuan/git/bestpick/phone/www/node_modules/electron
npm ERR! command failed
npm ERR! command sh -c -- node install.js
Downloading tmp-60315-0-electron-v4.0.4-darwin-arm64.zip
npm ERR! Error: GET https://github.com/electron/electron/releases/download/v4.0.4/electron-v4.0.4-darwin-arm64.zip returned 404
npm ERR! /Users/anhtuan/git/bestpick/phone/www/node_modules/electron/install.js:49
npm ERR! throw err
npm ERR! ^
npm ERR!
npm ERR! Error: Failed to find Electron v4.0.4 for darwin-arm64 at https://github.com/electron/electron/releases/download/v4.0.4/electron-v4.0.4-darwin-arm64.zip
So I go to https://www.npmjs.com/package/electron and find the latest version.
When I try to install it, this time it complains about Node.
% npm i
npm WARN old lockfile
npm WARN old lockfile The package-lock.json file was created with an old version of npm,
npm WARN old lockfile so supplemental metadata must be fetched from the registry.
npm WARN old lockfile
npm WARN old lockfile This is a one-time fix-up, please be patient...
npm WARN old lockfile
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: 'sharp@0.33.5',
npm WARN EBADENGINE required: { node: '^18.17.0 || ^20.3.0 || >=21.0.0' },
npm WARN EBADENGINE current: { node: 'v16.17.0', npm: '8.19.3' }
npm WARN EBADENGINE }
npm WARN deprecated boolean@3.2.0: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
Luckily I already have nvm installed.
% nvm
Node Version Manager (v0.37.2)
...
nvm install --lts Install the latest LTS version
nvm use --lts Use the latest LTS version
% nvm use --lts
Now using node v18.18.0 (npm v10.1.0)
anhtuan@MacMini www % nvm install --lts
Installing latest LTS version.
Downloading and installing node v22.12.0...
Downloading https://nodejs.org/dist/v22.12.0/node-v22.12.0-darwin-arm64.tar.xz...
################################################################################################################################################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v22.12.0 (npm v10.9.0)
It looks like nvm use --lts
uses the latest installed version of npm. Also, nvm install --lts
installs and sets up the current version of Node to that version. Good to know.
Finally npm i
completes without any warning
% npm i
added 1 package, and audited 83 packages in 1s
20 packages are looking for funding
run `npm fund` for details
1 high severity vulnerability
To address all issues, run:
npm audit fix
Run `npm audit` for details.
The last step is to download NW.js and run the webapp with it.
cd phone/www
% ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs .
MacOS tells me the binary is corrupted and attempts to move it to the bin.
This GitHub ticket says we can fix it with this command:
xattr -c nwjs.app
What does that command do?
That page tells me absolutely nothing. Let's ask ChatGPT:
This command uses the xattr
utility on macOS to manipulate extended attributes. Here’s a breakdown of the components:
xattr
: This command-line utility is used to view and manage extended attributes of files and directories in macOS.-c
: This flag tellsxattr
to clear all extended attributes of the specified file or directory.nwjs.app
: The target application or file whose extended attributes you want to clear.
Very nice! Then it says:
Checking Extended Attributes
Before clearing them, you can list the extended attributes with:
xattr -l nwjs.app
Example Output
com.apple.quarantine: 0083;00000000;Safari;1234ABCD-5678
Caution
Clearing extended attributes removes metadata, which might impact the functionality or security of the file. Be cautious when applying this to apps or files you don't fully trust.
Let's try on nwjs:
% xattr -l ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs
com.apple.quarantine: 0081;675ce76c;Chrome;
What does com.apple.quarantine do?
This attribute is added so that it can ask for user confirmation the first time the downloaded program is run, to help stop malware. Upon confirmation the attribute should be removed automatically, and then the program will run normally.
Alright, but MacOS does not actually ask me if I am ok running it. I guess that's why I should remove the flag with the commandline. Let's try it.
% xattr -l ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs
% ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs .
zsh: killed ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs .
Even though I cleared the quarantine flag, MacOS still says the archive is corrupted.
Then I realized that the ticket tells us to clear the flag on the .app archive, not the actual binary inside it.
% xattr -l ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app
com.apple.provenance:
com.apple.quarantine: 0081;675ce76c;Chrome;
% xattr -c ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app
anhtuan@MacMini www % ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs .
[1214/121239.031028:ERROR:zip.cc(179)] Cannot open '/Users/anhtuan/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/Resources/app.nw': FILE_ERROR_NOT_FOUND: No such file or directory (2)
Now it runs! But it is missing some file it says.
% cd Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/Resources
anhtuan@MacMini Resources % ls
af.lproj fil.lproj pt_BR.lproj
am.lproj fr.lproj pt_PT.lproj
app.icns gu.lproj ro.lproj
ar.lproj he.lproj ru.lproj
ar_XB.lproj hi.lproj scripting.sdef
bg.lproj hr.lproj sk.lproj
bn.lproj hu.lproj sl.lproj
ca.lproj id.lproj sr.lproj
cs.lproj io.nwjs.nwjs.manifest sv.lproj
da.lproj it.lproj sw.lproj
de.lproj ja.lproj ta.lproj
document.icns kn.lproj te.lproj
el.lproj ko.lproj th.lproj
en.lproj lt.lproj tr.lproj
en_GB.lproj lv.lproj uk.lproj
en_XA.lproj ml.lproj ur.lproj
es.lproj mr.lproj vi.lproj
es_419.lproj ms.lproj zh_CN.lproj
et.lproj nb.lproj zh_TW.lproj
fa.lproj nl.lproj
fi.lproj pl.lproj
Indeed the file is not there. How could the archive be incomplete? I have modified nothing.
This ticket seem to mention the node version: https://github.com/nwjs/nw.js/issues/7946
But I do have Node 22.
This one mentions packaging. Could it be that instead of a path, it expects a packaged webapp?
Let's check the NW.js documentation
In the Getting Started page, they do instruct to run it locally like so:
cd /path/to/your/app
/path/to/nw .
/path/to/nw is the binary file of NW.js. [...] On Mac, it’s nwjs.app/Contents/MacOS/nwjs.
Should I check out the documentation on how to package it?
https://nwjs.readthedocs.io/en/latest/For%20Users/Package%20and%20Distribute/
On Mac, put the files of your app into a folder named app.nw in nwjs.app/Contents/Resources/ and done.
Yes they do mention app.nw. But why is it that packaging might work, but not running locally?
It'd be nice if I could modify the code and always run the latest version without having to cp -R
every time. Let's try a simlink.
% cd ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/
anhtuan@MacMini Resources % ln -s ~/git/bestpick/phone/www app.nw
anhtuan@MacMini Resources % ls app.nw
app.nw config.xml img main.js package.json spec.html
bower.json css index.html node_modules res test.js
bower_components icon.png js package-lock.json spec tests
anhtuan@MacMini Resources % ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs
This time there is no error and the NW.js icon pops up in my task bar. However nothing shows up.
Seems unlikely but... Could it be that symlinks won't work?
% rm -rf app.nw
% cp -R ~/git/bestpick/phone/www app.nw
% ~/Downloads/nwjs-v0.94.0-osx-arm64/nwjs.app/Contents/MacOS/nwjs
Same results. It hangs.
I am not willing to put in anymore effort on it on MacOS. Let's try on Windows, and if it does not work, this webapp is officially dead.
Windows
> bower
bower : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Users\[username]\AppData\Roaming\npm\bower.ps1 파일을 로드할 수
없습니다. 자세한 내용은 about_Execution_Policies(https://go.microsoft.com/fwlink/?LinkID=135170)를 참조하십시오.
위치 줄:1 문자:1
+ bower
+ ~~~~~
+ CategoryInfo : 보안 오류: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
Even though I ran it in a Terminal window as Admin, it says UnauthorizedAccess.
The Bower website also simply says "install bower", run "bower install". What a joke.
Instead I try this
npm exec bower install
bower invalid-meta for:C:\Users\atn83\git\bestpick\phone\www\bower.json
bower invalid-meta The "name" is recommended to be lowercase, can contain digits, dots, dashes
It does seem to have run. They must have added new rules to app names since. Let's tweak the name and run the command again. Finally it works:
This time since we're on Windows, we can run the app by drag and dropping the webapp code into nw.exe. See https://nwjs.readthedocs.io/en/latest/For Users/Getting Started/:
Drag & Drop on Windows
On Windows, you can drag the folder containing package.json to nw.exe to run your app.
Let's accept
Aaaaaand still an empty window.
Good bye webapp
It was good while it lasted...
This reinforces my conviction that after 15 years, web development and Electron is really not for me anymore. It is just too much of a mess. Flutter for the win!