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.
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.
-
Clone the repository and enter the development shell:
-
Create your widget in
widgets-wasm/and add it to themembersof that folder'sCargo.toml; thejustcommands find widgets only there and inwidgets-wasm-examples/. Start from an official widget:widgets-wasm/clockfor layout and settings,widgets-wasm/weatherfor fetching data,widgets-wasm/braiins-poolfor credentials. More small examples (a calendar, a Pomodoro timer, a Home Assistant panel, a remote for Google Cast, DLNA and Kodi media players) are inwidgets-wasm-examples. For touch input, start fromwidgets-wasm/fleet-managementor the media remote. -
Declare your widget's settings as params in
manifest.json, then generate typed accessors: -
Preview it on your computer with hot reload. No Deck needed:
The testbed lets you switch viewports, change params and simulate system settings such as time zone and night mode.
-
Run the checks before you install:
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.
- Package the widget as a
.nararchive. The packaging guide shows the folder layout, manifest and launcher script, and the one command that creates the archive. - In the web interface, open Display Widgets and choose Install Widget.
- Read the notice about third-party widgets.
- Drop the
.narfile on the dialog, or choose it. - 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:
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.