Contact Sales

For Developers

The Deck's display software is open source. You can read it, build it, and write widgets that run next to the official ones. Everything on this page is optional: you never need it to use the Deck.

The code lives in the bmc-main repository on GitHub, licensed under the GNU GPL version 3 or later. The repository's README is the full reference; this page gives an overview.

How the Display Works

The Deck runs a Linux system with a Wayland compositor. Each widget is a WebAssembly (WASM) module with its own small launcher process; the modules run in the Deck's shared widget runtime. The compositor places widgets into scenes, forwards touch input to them, and runs the scene transitions.

A widget builds a declarative UI tree. The runtime handles layout, text shaping, rendering and animation. Through the SDK, a widget can also fetch data over HTTP, store state, react to touch, and drive the light strip.

Each widget ships with a manifest.json that declares its identity, name, icon, the display sizes it supports, and its settings. The web interface builds the widget's settings form from the manifest, so a new widget needs no changes to the Deck's web interface.

Display Sizes

A widget receives its drawing area from the host and should not hard-code dimensions.

Placement on the DeckSize in the web interfacePixels
Fullscreen sceneFull1280 x 480
Combined scene, 1 by 1 slotSmall317 x 238
Combined scene, 2 by 1 slotsMedium638 x 238
Combined scene, 2 by 2 slotsLarge638 x 480

The same runtime also drives the display of the Braiins Mini Miner BMM101 (480 x 320). Declare only the viewports you have designed for: a widget appears in the picker only on devices whose sizes it supports.

Write a Widget

You need a Linux computer with Git, Git LFS and Nix with flakes enabled. The Nix development shell provides the Rust toolchain. To run the desktop testbed you also need mprocs and the graphics, input and audio libraries listed in the repository's README.

  1. Clone the repository and enter the development shell:

    git clone https://github.com/BraiinsForge/bmc-main.git
    cd bmc-main
    git lfs install && git lfs pull
    nix develop
  2. Create your widget in widgets-wasm/ and add it to the members of that folder's Cargo.toml; the just commands find widgets only there and in widgets-wasm-examples/. Start from an official widget: widgets-wasm/clock for layout and settings, widgets-wasm/weather for fetching data, widgets-wasm/braiins-pool for credentials. More small examples (a calendar, a Pomodoro timer, a Home Assistant panel, a remote for Google Cast, DLNA and Kodi media players) are in widgets-wasm-examples. For touch input, start from widgets-wasm/fleet-management or the media remote.

  3. Declare your widget's settings as params in manifest.json, then generate typed accessors:

    just wasm::gen my-widget
  4. Preview it on your computer with hot reload. No Deck needed:

    just wasm::dev my-widget

    The testbed lets you switch viewports, change params and simulate system settings such as time zone and night mode.

  5. Run the checks before you install:

    just validate

The widget developer guide covers params, credentials, timers, memory, display geometry and visual regression tests. Run just wasm::docs for the SDK API reference.

Install Your Widget

From the web interface

The easiest way to install a finished widget is to upload it.

  1. Package the widget as a .nar archive. The packaging guide shows the folder layout, manifest and launcher script, and the one command that creates the archive.
  2. In the web interface, open Display Widgets and choose Install Widget.
  3. Read the notice about third-party widgets.
  4. Drop the .nar file on the dialog, or choose it.
  5. Choose Accept the Risk and Install.

The Deck checks the archive before it installs anything. It reports whether the widget was newly installed, upgraded, reinstalled or already present, and the widget appears in the widget picker at once. A rejected upload leaves the Deck as it was.

The Deck checks the package format, not what the widget does. Install widgets only from people you trust.

Limits: one widget per archive, at most 64 MiB and 4096 files and folders. The Deck refuses a version older than the one installed, a uid that belongs to another installed widget, and a package that declares helper programs. To update your widget, keep the same uid and raise the version. An uploaded widget cannot bring a settings migrator: after an upgrade it keeps the settings it still knows and gets defaults for new ones. The packaging guide lists the remaining rules.

Over SSH, for development

For fast iteration, deploy straight from your checkout. The Deck accepts SSH logins as root, with the password you set in the web interface. The Deck needs software 26.09 or later. Update it to the latest version before you start; see Upgrades. Deploy everything once, then single widgets:

DEVICE_IP="<your-deck-address>"
ssh-copy-id root@"$DEVICE_IP"
nix run .#deck -- deploy --device "$DEVICE_IP"
nix run .#deck -- deploy --device "$DEVICE_IP" --packages widget-my-widget

Track new files in Git before you deploy: Nix ignores untracked files.

Deploying from a checkout turns automatic updates off, so an update does not replace your build. Turn them back on in System Settings, Upgrades when you are done.

Credentials and Security

WebAssembly widgets never read the secrets users give them. A user saves a token or password once as a connected account and binds it to a widget. The widget learns only that a credential is available and which account it came from. The widget puts a placeholder in a request, and the Deck's runtime fills in the secret at the moment the request leaves.

The widget still chooses where that request goes. Account kinds tied to a service, such as a Braiins Pool token, are sent only to that service; a request that would carry them anywhere else is refused. Token and Username & password accounts go wherever the widget sends them, unless the user fills in Allowed destinations for the account.

Saved credentials are stored unencrypted in a file that only the Deck's administrator can read. They are kept out of logs and support archives.

Get Involved

Report issues and propose changes in the bmc-main repository.


Was this helpful?