Today I encountered a classic "works on my machine... wait, no it doesn't" moment while setting up the Opencode Desktop project. Running bun run dev failed with a cryptic Error: Electron uninstall message. Here's the full story of how I diagnosed and fixed it.
The Symptom
Running bun run dev in the packages/desktop directory would build successfully through Vite and electron-vite, then crash at the final step:
|
The build completed, but Electron itself couldn't launch.
Root Cause Analysis
Step 1: Check Electron Installation
First, I checked if the electron npm package was installed:
|
Looks present. But node_modules/electron was actually a symlink to Bun's global package store:
|
Step 2: Check the Actual Binary
The electron npm package is just a downloader wrapper. The actual Chromium binary lives in dist/. Let's check:
|
Only a LICENSE file! The actual Electron.app bundle was missing. The binary had never been extracted.
Step 3: Why Didn't Postinstall Work?
Electron's package.json includes a postinstall script that runs node install.js. This script:
- Checks if
dist/versionandpath.txtexist - If not, downloads the platform-specific zip via
@electron/get - Extracts it via
extract-zip
The zip was already cached locally:
|
So download worked. But extraction didn't. I wrote a test script to verify extract-zip behavior:
|
Output:
|
extract-zip v2.0.1 was returning a promise but resolving instantly without doing the work, causing the install script to exit cleanly before extraction completed. This appears to be a compatibility quirk with Node.js v24 and the specific extract-zip version used by Electron 42.3.3.
Step 4: The Smoking Gun — path.txt
Even if extraction had worked, I later discovered another issue. The install.js script creates path.txt containing the relative path to the Electron executable. When I manually created this file, I initially used echo:
|
This added a trailing newline (0x0a), which caused a hilarious secondary error:
|
Note the \n in the path! Always use printf without a newline for machine-readable path files:
|
The Fix
Since the automated install script couldn't extract the archive, I performed a manual surgical fix:
|
Verification:
|
Then bun run dev worked perfectly — the Electron app launched, connected to the Vite dev server, and the sidecar initialized.
Lessons Learned
-
Symlinks obscure the real problem: When using Bun or pnpm, packages live in a content-addressable store. The
node_modules/electrondirectory you see isn't where the actual files are. -
Don't trust postinstall in modern package managers: Bun's installation strategy sometimes doesn't play well with native binary postinstall scripts, especially ones using older extraction libraries.
-
echois dangerous for file contents: That trailing newline cost me an extra debugging cycle. Useprintforecho -nwhen writing exact strings. -
Cache is your friend: The 120MB zip was already in
~/Library/Caches/electron/. No need to re-download — just extract it properly.
Reference
- Electron package store path:
node_modules/.bun/electron@42.3.3+*/node_modules/electron - Electron cache:
~/Library/Caches/electron/(macOS) - Expected
distcontents after extraction:Electron.app/,LICENSE,LICENSES.chromium.html,version - The
path.txtformat: plain relative path, no newline, pointing to the executable insidedist/