// OPENBOX DOCS

Interfaces and data

Understand OpenBoxGL interfaces, local state, and environment selection.

OpenBoxGL ships two interfaces that share one local library. This page explains what you see, how the pieces fit together, and exactly where your data lives so you can back it up, move it, or diagnose problems.

The two interfaces

InterfaceEntry pointWhat you seeBest for
Web UIpython3 web_app.py or openboxA chrome-less app window by default (falls back to your browser) with a three-column workspace: filter sidebar, cover grid or list, detail paneFull feature set, REST API, Big Box mode
Native UIpython3 openbox.py or openbox-nativeA regular Tk desktop window with the same libraryLightweight desktop use

Web UI

Starting the Web UI does three things in order:

  1. Bootstraps the environment and configures the diagnostic log in the data directory.
  2. Loads and normalizes the library state (running migrations if the schema is older), starts a ThreadingHTTPServer bound to 127.0.0.1 on a random port, and writes server.port and server.token into the data directory.
  3. Prints http://127.0.0.1:PORT/?token=... and opens it in your browser, unless --no-browser is passed.

The server is loopback-only, so nothing is reachable from the network. The URL carries the per-launch token in the query string; the API also accepts the same value as an X-OpenBox-Token header. When the server stops, both files are deleted. A second instance therefore gets a fresh token and port, and the files are shared between interfaces: the keyboard launcher (scripts/openbox-launcher.sh) and openbox:// deep links read these two files to find and authenticate against the running server. See Command line and deep links for the full flag and URI reference.

Native UI

The Tk window opens the same library.json with the same grid, search, filters, and launch profiles, minus the browser surface. Both processes coordinate writes through a file lock, so running the Web UI and the native UI against the same library at the same time is safe; the last writer wins per transaction, not per file.

Where data lives

The default data directory is ~/.local/share/openbox-game-launcher. Everything OpenBoxGL persists lives there:

Path (inside the data directory)Contents
library.jsonThe library: games, profiles, history, settings, playlists, queue, notifications
library.json.bakLast-known-good copy, rewritten before every commit
.library.json.lockCross-process lock file coordinating concurrent writes
server.token, server.portPer-launch credentials for the running Web UI; deleted on exit
openbox.log (+ .1....4)Rotating diagnostic log with secrets redacted
backups/Library backup archives (OpenBoxBackup-*.zip)
save-backups/Versioned per-game save backups with retention limits
media/Downloaded artwork, screenshots, video, and metadata media, grouped by source
themes/Stock themes plus locally imported CSS themes
plugins/Installed local plugin packages
metadata/The synced LaunchBox Games Database file
cache/Archive extraction and RetroAchievements working files
media-queue.jsonPending media download jobs
highscores/, bezels/MAME high-score exports and bezel downloads

The library file itself is schema-versioned JSON with stable game IDs derived from game identity, never from list position. That is why playtime, queue entries, and save links survive reordering or deleting other entries.

Changing the data directory

Set OPENBOX_DATA_DIR in the process environment before starting OpenBoxGL:

OPENBOX_DATA_DIR=/mnt/library openbox

Two details matter:

  • The variable is read at startup, before .env bootstrap. Putting it inside a discovered .env file is too late for this choice; export it in the shell, a desktop entry, or a systemd unit instead.
  • If the directory does not exist, it is created on first write. Migrate an existing library by moving the whole data directory (not just library.json) and pointing the variable at the new location; the sidecar, media, and backups should move with it.

Legacy data

When OPENBOX_DATA_DIR is not set and no library.json exists yet, OpenBoxGL looks for the legacy path ~/.local/share/launchbox-linux/library.json and copies it into the new data directory, so an earlier test install keeps its library.

Configuring credentials

Credentials and tokens can come from three places, in order: the process environment, discovered .env files, and persisted application settings (Settings dialog). The .env search order is the OPENBOX_DATA_DIR you passed in, the parent of the data directory, the current working directory, the application directory, your home directory (~/.env), and ~/.config/openbox-game-launcher/.env. Values already in the environment are never overridden by .env.

Supported variables are documented in .env.example and Configuration; they cover RetroAchievements (RETROACHIEVEMENTS_USERNAME, RETROACHIEVEMENTS_API_KEY), EmuMovies, IGDB, and GITHUB_TOKEN for release-API rate limits. Keep these files private; the API and the diagnostic log redact the values, but a .env file itself is plaintext.

Security model

  • The server binds to loopback and requires the session token on every request. Prefer the X-OpenBox-Token header for API calls you write; a token query parameter can leak into browser history and server logs.
  • Tokens, passwords, API keys, and authorization headers are redacted in the diagnostic log.
  • Webhooks reject plain HTTP targets by default; OPENBOX_ALLOW_HTTP_WEBHOOKS=1 enables them for trusted local tests only.
  • No OpenBox account exists and no library data leaves your machine except what an integration you explicitly trigger sends.

Backups and recovery

The state store writes atomically: it writes the backup copy from the temp file first, then swaps the primary into place, so a crash cannot pair a fresh primary with a stale backup. If the primary file ever fails to decode, OpenBoxGL preserves the original, raises a clear error, and recovery must be explicit. Restore paths and archive members are validated, symlink parents are rejected, and a pre-restore safety copy is created automatically.

Make a backup before major changes: Settings has a backup manager, and python3 web_app.py --backup creates an archive from the command line. See Data and recovery and Library backups.

Troubleshooting orientation

  • App starts but no browser: run from a terminal and open the printed URL, or pass --no-browser and drive the API yourself.
  • App starts but the library looks empty: check OPENBOX_DATA_DIR; the server is reading a different directory than the one you edited.
  • Launch fails: the detail pane names the missing piece (executable permission, launch command, platform profile, or path). Check the diagnostic log for the backend's view.

Related: Configuration, Data and recovery, REST API, Troubleshooting.