The desktop app¶
vibe-viewer desktop opens the viewer in a native window: an Electron shell
with OS menus, file dialogs, drag-and-drop, an Open Recent list and, on
macOS, a Finder file association for .qvf. The same code targets macOS,
Windows and Linux.
vibe-viewer desktop # a window on the browse page for the current directory
vibe-viewer desktop water.qvf # a window with water.qvf loaded
vibe-viewer desktop --port 9090 # the server port behind the window; 8765 by default
It works from any directory. On first run it downloads the reviewed Electron
runtime, about 120 MB, and brands it as vibe-viewer; pass --with-electron to
install.sh to fetch it during installation instead.
Note
The desktop app is a thin native shell around the same Python server the
browser viewer uses: it starts vibe-viewer serve in the background and shows
it in a window. Everything on The browser viewer and
Building and editing applies unchanged. What the shell adds
is the window, the menus and the file association.
What is available today¶
Route |
Status |
|---|---|
|
The supported route, on macOS, Linux and Windows. |
Apple Silicon |
Buildable locally with Python, PyVista, VTK, Trame and RDKit included. Requires macOS 14+. Developer ID signing and notarization remain release work. |
Linux x86-64 AppImage |
Self-contained runtime; see Linux desktop for host requirements. |
Windows NSIS installer |
Buildable shell requiring an external Python environment; Windows qualification remains incomplete. |
The Python wheel carries the browser, terminal and headless surfaces but not the Electron source, so the CLI’s desktop command needs the checkout. The self-contained Apple Silicon and Linux x86-64 packages instead run their included interpreter, including for each per-file viewer; they ignore external Python environments. On macOS, copy the app from the DMG to Applications and open it. No Python, pip, Homebrew or Node.js installation is needed for normal viewing, editing or image capture.
External calculation engines and companion applications remain separate. The bundled profile includes common format readers and SMILES conversion; ASE’s additional formats, TREXIO and notebook widgets remain optional source extras. See Desktop packaging design for the runtime scope and build instructions. Locally built ad-hoc previews do not provide Gatekeeper trust or establish Mac App Store readiness.
Installing¶
The following commands install from source. They are unnecessary for the self-contained Apple Silicon app.
Clone the public source repository:
git clone https://github.com/vibyverse/vibe-viewer.git
Then enter the checkout before following your platform’s install commands:
cd vibe-viewer
macOS and Linux. The lifecycle installer creates the environment and records it for direct app launches:
./scripts/install.sh --with-electron # or plain install.sh; Electron then downloads on first launch
source .venv/bin/activate
vibe-viewer desktop
Desktop mode needs a profile that contains the viewer: modes (the
default), viewer, all or test. core and tui are non-desktop
profiles.
Windows. The shell scripts are macOS and Linux only. Create the environment by hand from PowerShell in the checkout root:
py -3.12 -m venv .venv
.venv\Scripts\python.exe -m pip install -e ".[viewer]"
.venv\Scripts\vibe-view.exe --version
.venv\Scripts\vibe-view.exe desktop
Repeat the pip install -e line after updating the checkout.
Run install, update, reinstall and uninstall as your regular login user,
without sudo. Privileged interactive execution is refused so it cannot
leave a root-owned environment the desktop session cannot maintain, and on
Linux the app refuses to launch as root outright, because Electron’s sandbox
does not support it.
Dock tile and shell command (macOS)¶
./scripts/install.sh --with-electron --dock --link-bin /opt/homebrew/bin
--dock pins the source-backed vibe-view.app to the Dock and asks the
Dock to reload; running it again is a no-op. --link-bin DIR writes a
marked vibe-view launcher into an existing writable directory on your
PATH and refuses to overwrite a file it did not create. Both are recorded:
uninstall.sh removes them with the installation, and re-running
install.sh with the same flags refreshes them after the checkout moves.
--adopt-desktop lets this checkout take over a source app another
checkout installed.
Updating and repairing¶
./scripts/update-desktop.sh # checkout + Python environment + Electron + the source app
./scripts/reinstall.sh --desktop # rebuild the environment and refresh Electron, no Git
./scripts/uninstall.sh --dry-run # what a removal would take
Quit every desktop window first. update-desktop.sh validates the Electron
engine and synchronizes a missing, corrupt or mismatched one to the reviewed
version in package-lock.json; on macOS it also refreshes the Applications
copy and its displayed version. It records which checkout owns the source
app and refuses to take over one from another checkout unless you pass
--adopt-desktop; inspect the path it reports first. It never replaces a
packaged app, and on Linux there is no Applications copy: the updater
synchronizes Electron and its wrappers, and the window keeps starting
through vibe-viewer desktop.
uninstall.sh removes this checkout’s Electron runtime, its macOS source
app and the Dock tile or command link; --keep-desktop keeps the Electron
download for a later reinstall. Settings, recents, logs, window state, your
archives and the app-managed environment described next are preserved.
Opening files and quitting¶
Use File → Open QVF, TREXIO or ORCA File… (Ctrl/⌘ O) for a QVF or supported loose file, Open Recent to return to a previous path, or drag a file into the window. File → Open Folder… (Ctrl/⌘ Shift O) browses an ordinary directory; a TREXIO text directory is treated as one dataset and needs the TREXIO reader. Browse Directory (Ctrl/⌘ B) returns to the server’s directory browser.
These native dialogs select files on the desktop application’s machine. Inside the viewer, Browse chemistry file… follows the browser upload workflow described in opening files. Opening a loose file converts it for inspection; use the import command or a geometry save action when you want a persistent output archive.
Closing the last window does not quit the application. It remains running in the tray/menu bar and keeps its server alive. Use Quit from the tray menu, vibe-viewer → Quit / ⌘Q on macOS, or File → Quit on Linux and Windows. Quitting stops the desktop-managed server and console; queue jobs submitted separately have their own lifecycle.
Before updating or repairing, save edited geometry and any views you want to retain, then quit the app explicitly. A session file saves the view; it is not a substitute for saving edited coordinates.
First run: the setup screen¶
Self-contained macOS and Linux packages validate their embedded runtime. If it cannot start, the repair screen suggests restarting or replacing the application, keeping your documents and settings. It never asks you to install Python or tries a different interpreter from your machine. The discovery and setup instructions below apply to source launches and shells without a bundled runtime, including the Windows target.
When the app starts it looks for a Python that can run the server, in this
order: the interpreter recorded by an earlier vibe-viewer desktop launch,
then python3, python, python3.13, python3.12 and python3.14 on
PATH (py and python on Windows), then the app-managed environment at
$XDG_DATA_HOME/vibe-view/venv (by default ~/.local/share/vibe-view/venv),
then a development checkout’s .venv.
If none of those can import vibeview with the [viewer] extra, the app
does not fail. It shows a setup screen naming which of three cases
applies (no Python, Python but no vibe-viewer, vibe-viewer but no [viewer]
extra), with a command that creates a dedicated virtual environment at the
app-managed path and installs into it, a Copy button, and an
I’ve installed it — recheck button that re-scans without restarting.
Two things about that command are worth knowing:
It installs into a fresh virtualenv on purpose. Homebrew Python and the Debian, Ubuntu and Fedora system Pythons are marked externally managed (PEP 668) and refuse a plain
pip install; a fresh virtualenv never is. The app looks for that environment on every start, so Recheck finds it with no further step.The requirement it composes names a wheel by URL for the app’s exact version. Until the distribution is published, use the source checkout instead: from the checkout root, with the app still open,
python3 -m venv ~/.local/share/vibe-view/venv ~/.local/share/vibe-view/venv/bin/pip install -e '.[viewer]'
then press Recheck.
Launching with vibe-viewer desktop from an environment that already has the
viewer records that interpreter, so the setup screen is skipped from then
on.
macOS: double-click a .qvf¶
vibe-viewer desktop FILE works immediately after install. A Finder
double-click needs the app bundle, which install.sh --with-electron
installs as vibe-view.app in Applications and brands with every format the
viewer reads: .qvf, .py inputs and the loose structure and volume
formats. Right-click → Open With → vibe-viewer therefore works for all of
them, and a .py input opens with its structure loaded. The handler rank is
Alternate: vibe-viewer never takes over the default association for Python
files.
macOS usually picks up the declarations on first launch. To force a refresh:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \
-f /Applications/vibe-view.app
To build a distributable package yourself:
cd electron
./build-desktop.sh # dist/mac-arm64/vibe-view.app (dist/mac/ on Intel) and a .dmg
That is a local development artifact, ad-hoc signed but not Developer
ID-signed or notarized, so Gatekeeper may block its first launch:
right-click the app and choose Open once. Signing and notarization are
the gate on a downloadable, self-updating package, and they remain a roadmap
item; electron/PUBLISHING.md has the details.
Linux¶
Electron needs the usual GTK3 desktop runtime, which a desktop installation already has. On a minimal Debian 12 or Ubuntu 22.04 system:
sudo apt-get install libgtk-3-0 libnss3 libatk-bridge2.0-0 \
libdrm2 libxkbcommon0 libgbm1 libasound2
Debian 13 and Ubuntu 24.04 use the time64 package names:
sudo apt-get install libgtk-3-0t64 libnss3 libatk-bridge2.0-0t64 \
libdrm2 libxkbcommon0 libgbm1 libasound2t64
If a container or a host security policy blocks Chromium’s user namespaces,
configure a supported sandbox policy when you can. For a trusted local file,
vibe-viewer desktop --no-sandbox is the explicit last resort; it prints a
warning, because it reduces isolation.
Windows¶
vibe-viewer desktop from a source checkout is the route here too, with the
manual environment above. An NSIS installer target exists in electron/,
but no Windows artifact is published, and the installer is unsigned.
Warning
The Windows target has not been verified on a real Windows machine. It
is developed and tested on macOS and Linux; the py-launcher discovery, the
setup screen and the NSIS build have not been run on Windows, and the app
says so in a one-time notice on its first Windows launch. If you try it,
whether it works or not,
open an issue:
that feedback is what will make Windows a first-class target, and you will
get help with whatever you hit.
Troubleshooting¶
The setup screen keeps appearing after I installed vibe-view. The app
scans the fixed interpreter list above plus the one recorded by a previous
vibe-viewer desktop launch. An environment that is on neither list is
invisible to a bare double-click. Run vibe-viewer desktop once from that
environment; it records the interpreter under the cache directory, and later
source launches and double-clicks reuse it. This does not change a packaged
app’s embedded interpreter. Confirm the environment is capable
with:
python -c "import vibeview, trame, uvicorn; print('ok')"
“The vibe-viewer server did not start.” Older builds showed this and quit; current builds route the same conditions to the setup screen, which names what is missing.
“Could not open” instead of the viewer. The viewer process for that file stopped before it was ready, most often because the file is not a valid archive. The page shows the exit status and the viewer’s error message. Choosing the file again from the browse page or Open Recent starts a new attempt, so fix the file first.
Check for Updates depends on how the app was installed. Source launches
show checkout-update instructions; they do not query the packaged updater or
change Git. Quit and run ./scripts/update-desktop.sh from the owning
checkout. A packaged macOS arm64 build uses its configured update feed when
the updater is available. An ad-hoc-signed macOS build can offer a manual
download but cannot self-install; self-installation requires a Developer ID
signature. Feed contents determine whether an update is offered.
Linux and Windows builds show replacement-package guidance rather than
querying the macOS feed.
The window is blank or unresponsive. The shell is showing the browser
viewer, so the browser troubleshooting
applies: most often a port that something else holds. --port moves the
server.
Self-contained Linux desktop¶
Linux x86-64 AppImages include Python and the application libraries. No external Python, pip, Node.js or source checkout is needed. Download the package and its SHA-256 checksum from the downloads page. Linux desktop downloads are public and require no supporter membership. macOS and Windows Store editions are planned paid purchases; their availability is separate from Linux downloads.
The initial Linux target is Debian 12 or Ubuntu 24.04 on x86-64 with a graphical
desktop and standard GTK3, NSS, ALSA, OpenGL and X11/Wayland compatibility libraries.
Make the AppImage executable and launch it as a regular user. If FUSE is not
available, extract with --appimage-extract and launch squashfs-root/AppRun.
The application and Python runtime remain inside that directory. Offline local
work is supported; remote services and external calculation engines remain optional.
Linux updates currently use replacement AppImages from the website.
Build natively on Linux x86-64 using electron/build-desktop.sh --linux. The
Linux runtime lock pins interpreter and wheel hashes; the builder checks native
library resolution and the installed runtime before packaging.
Python console¶
Choose View → Python Console (Ctrl/⌘ Shift P). Write Python in the editor and
press Run or Ctrl/⌘ Enter. The last expression’s value, printed output and
tracebacks appear above the editor. Variables persist between executions; _
holds the last expression value. Stop and reset terminates the console
process and starts the next execution with fresh variables. Closing the console
also clears its process. It does not stop calculations submitted separately to a
queue.
The console uses the desktop application’s selected Python interpreter and
working directory, including the packaged interpreter in a bundled app. It
preloads api (vibeview.api), np (NumPy), ModelScene, SceneCommands and an
empty scene. For example:
api.info("water.qvf")
coordinates = np.array([atom["position"] for atom in api.get_structure("water.qvf")["atoms"]])
coordinates.mean(axis=0)
The console is a local Python environment with your account’s permissions, not a sandbox. Its execution bridge is available only to the dedicated desktop console window; ordinary browser pages do not receive it. The console’s scene is independent of the live browser scene. Exchange working models using saved scene JSON:
import json
from pathlib import Path
scene = ModelScene.from_dict(json.loads(Path("scene.json").read_text(encoding="utf-8")))
scene.select("element O")
Path("modified-scene.json").write_text(
json.dumps(scene.to_dict(), allow_nan=False), encoding="utf-8"
)
Paste the saved JSON into the browser’s Working model scene restore field. See model scenes for scene commands and replay. Output is bounded in the console display; save large arrays or reports explicitly to files.