# MeshBay desktop client The interface ships **inside this package** and loads from disk. A shell that points a WebView at the hub's `/app/` is a browser with a different icon and fixes nothing — that is finding T3, and removing it is the reason this exists. ## Building Needs **Node ≥ 22**. Ubuntu 24.04 ships nodejs 18, which cannot install Electron at all: the download script `require()`s an ESM module, which Node gained only in 22. Fedora 44 is fine. # once, on a machine whose distro is too old: curl -fsSLO https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-x64.tar.xz curl -fsSLO https://nodejs.org/dist/v24.19.0/SHASUMS256.txt grep " node-v24.19.0-linux-x64.tar.xz$" SHASUMS256.txt | sha256sum -c - sudo tar -xJf node-v24.19.0-linux-x64.tar.xz -C /opt/nodejs --strip-components=1 export PATH=/opt/nodejs/bin:$PATH npm ci # not `npm install` — the lockfile is the build input # npm ≥ 11 blocks install scripts by default; Electron needs them npm approve-scripts electron node node_modules/electron/install.js # Chromium's namespace sandbox requires SUID on chrome-sandbox sudo chown root:root node_modules/electron/dist/chrome-sandbox sudo chmod 4755 node_modules/electron/dist/chrome-sandbox npm run sync-ui # copy the interface from the hub package npm start `ui/` is generated and is not committed. The interface has exactly one source, `packages/meshbay-hub/src/meshbay_hub/static/`, and a silent fork is the only real way to end up maintaining it twice. ## Running headless xvfb-run -a ./node_modules/electron/dist/electron --no-sandbox . ## What it does not have **No service worker.** Chromium refuses to register one on a custom scheme, so the streamed-download path never runs here — the application saves through a native dialog instead, which is the better of the two. `sw.js` is still shipped because the same files serve the browser, where it is one of only three ways to write a large file. **No direct network from the renderer.** Its origin is `app://meshbay`, which CORS refuses, and the hub has no CORS middleware at all — a posture worth keeping. Every hub call leaves from the main process, which refuses any origin that is not the hub the user signed in to.