electron-vite caps at Vite 7 and the project runs Vite 8, so the Electron shell got wired by hand. Then came the white window, unsigned packaging, and an icon from the navbar glyph.
The browser board has a ceiling: folder access needs Chrome, permissions lapse on reload, and there is no way to watch a folder for changes. The desktop build exists to remove all three. Phase one was supposed to be electron-vite, until its peer dependencies stopped at Vite 7 and this project runs Vite 8.
Wired by hand
Instead of downgrading Vite for one plugin, the Electron shell is three small pieces. A Vite library build compiles electron/main.ts and electron/preload.ts into out/. The main process opens a window with context isolation on and Node integration off, loading the dev server in development and dist/index.html packaged. The preload exposes a minimal bridge. Two npm scripts, electron:dev and electron:build, and no new framework to learn.
The white window
The first launch showed an empty white window with the correct title. index.html loaded, but every asset used an absolute path, which resolves to the filesystem root under file:// instead of the app bundle. One line in the Vite config, base: './', fixed it. The title rendering while the body stayed blank was the clue: HTML found, assets lost.
Packaging and the icon
electron-builder produces an unsigned macOS dmg, since there is no Apple signing identity on this machine. Signing was disabled in config rather than fought, and first launch needs the right-click Open workaround. The app icon is the same Tabler kanban glyph as the navbar, teal on near-black, rendered to PNG and converted to .icns with system tools.
Where it stands
npm run dist ships a real installable app with its own icon. It opens, it renders, it carries no browser permission model. The main-process file API and the renderer backend came next, replacing the File System Access path with direct disk access and user-data persistence.