Desktop App - UpstandPlatform/OpenRive GitHub Wiki
OpenRive ships a desktop build made with Electrobun: a small native window around the same editor, with the embedded PostgreSQL database in your user data folder. No browser tab, no server to start.
Every release has installers attached, built on GitHub Actions:
| Platform | File |
|---|---|
| macOS (Apple Silicon) | macos-arm64-OpenRive.dmg |
| Windows | win-x64-OpenRive-Setup.zip |
| Linux | linux-x64-OpenRive-Setup.tar.gz |
Builds for a branch or pull request are available as workflow artifacts from the Desktop workflow run.
Releases are made from the Desktop workflow — no version-bump commit needed:
- Actions › Desktop › Run workflow.
- Choose what to release:
patch(default),minor,major, ornonefor artifacts only. - Optionally tick pre-release or draft, and pick the Electrobun channel.
The workflow takes the newest v* tag, increases it, stamps that version into electrobun.config.ts and the
package manifests, builds on macOS, Windows and Linux, creates the tag, and publishes a GitHub release with all
installers attached and generated release notes.
Pushing a tag by hand still works and releases exactly that version:
git tag v1.2.0 && git push origin v1.2.0Version numbers therefore live in the tags; the version fields in the repository are only defaults for local
builds.
The desktop window has no native title bar (titleBarStyle: 'hidden'), and there is no extra bar in its place: the
app's own top bars are the window handle, so no vertical space is spent on chrome.
| Part | What it does |
|---|---|
| The project header, or the editor's toolbar | Drag any empty part of it to move the window |
| Minimise / Maximise / Close | At the right end of that bar, just after the user avatar |
| Help, in the user menu and in the editor's OpenRive menu | Documentation, openrive.upstand.dev, the GitHub repository and reporting an issue — all open in your normal browser |
Dragging is CSS: the bars carry .window-drag (apps/web/src/app/globals.css), and everything interactive inside
them is marked no-drag so it stays clickable. The rules set --electrobun-app-region as well as
-webkit-app-region, because that custom property is what the Electrobun preload reads — the CSS build drops the
prefixed property, a custom property always survives.
The window buttons and the external links reach the native window through a tiny control server the main process
listens on at 127.0.0.1, which only answers requests carrying a token generated for that run — the page is served
over http:// rather than from views://, so it cannot use the bundled RPC bridge.
Everything desktop-only lives in apps/web/src/components/desktop.tsx and renders nothing in a browser tab, so the
same components are safe in the shared header and toolbar.
A packaged app updates itself from this project's GitHub releases — release.baseUrl in electrobun.config.ts
points at releases/latest/download, and the release carries the update.json, .tar.zst and .patch files the
updater needs (delta patches first, the full bundle as a fallback).
The app checks quietly a few seconds after launch. Whatever it finds is shown in the user menu (and in the editor's OpenRive menu), under the running version:
- Check for updates — check now, if the quiet check has not run yet.
- Download x.y.z — appears once a newer version exists.
- Restart to install x.y.z — quits, swaps the app in place and starts the new version.
Nothing is downloaded or installed without being asked for. Builds made from source report Updates are managed outside the app in this build, because only the stable and canary channels have a release to update from.
- The main process (Bun, bundled) starts the Next.js standalone server on a free local port and opens a window on it.
- Projects live in the platform's user data folder (
Utils.paths.userData/data), in the embedded database. - Setting
DATABASE_URLbefore launching points the app at a shared PostgreSQL instead, so a team can use the same projects from the desktop app and a self-hosted server.
bun install
bun run --cwd apps/desktop build:server # Next.js standalone bundle
bun run build:desktop # hutch/electrobun build --env=stableArtifacts land in apps/desktop/artifacts/. Electrobun does not cross-compile: build each platform on that platform.
Requirements: Bun 1.4+, plus the platform toolchain Electrobun needs (Xcode command line tools and cmake on macOS;
Visual Studio Build Tools and cmake on Windows; build-essential cmake pkg-config libgtk-3-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev libpipewire-0.3-dev librsvg2-dev on Ubuntu). The first build downloads the Electrobun
toolchain into ~/.hutch.
To run it in development:
bun run desktop # builds the server bundle, then electrobun devThe icon is the OpenRive logo (apps/web/public/logo.svg) on a white rounded square, the same badge the web app
shows in its header:
| Path | Used for |
|---|---|
apps/desktop/assets/icon-win.png (256×256) |
Windows: Hutch converts it to the .ico used by the installer, shortcuts and taskbar |
apps/desktop/assets/icon.png (512×512) |
Linux |
apps/desktop/assets/icon.iconset/ |
macOS, converted to .icns by iconutil on the macOS runner |
Windows must be 256×256 at most — that is the largest image an
.icocan hold, and a bigger PNG fails the build withinvalid Windows PNG icon: PngTooLarge.
To regenerate them after changing the logo, render logo.svg onto a white rounded square (corner radius 22% of the
size, logo at 70%) and export PNGs at 16, 32, 48, 64, 128, 256, 512 and 1024 px. The .iconset folder needs
icon_16x16.png, [email protected], icon_32x32.png, [email protected], icon_128x128.png,
[email protected], icon_256x256.png, [email protected], icon_512x512.png and [email protected], where
each @2x file is the next size up.
| Path | What |
|---|---|
apps/desktop/src/bun/index.ts |
Main process: starts the server, opens the window, window controls and updates |
apps/web/src/components/desktop.tsx |
Window buttons, Help links and the update menu, all desktop-only |
apps/desktop/assets/ |
Application icons |
apps/desktop/src/mainview/ |
Fallback view shown if the server does not start |
apps/desktop/electrobun.config.ts |
App name, identifier, bundle contents |
scripts/bundle-desktop-server.ts |
Builds and stages the standalone server |
.github/workflows/desktop.yml |
Per-OS builds and artifact upload |
This page is generated from docs/desktop.md. Suggest an edit.