A few notes on app and watchface development for the Mi Band 10
I needed a new watch — something cheap but genuinely useful, and ideally hackable. A Mi Band 10 fit the bill, and I picked one up with the intention of building a few apps for it.
The information problem
If you can't read Russian or Chinese, documentation is essentially nonexistent. English-speaking communities for the Mi Band 8 and later just don't seem to exist. With the help of online translators I managed to piece together the following:
- There are two distinct types of apps
- There are two similar-but-different programs for creating watchfaces
The two types of apps
The first type are .rpk files — Xiaomi Vela JS "Quickapps". The second are watchface apps: apps embedded inside watchfaces rather than distributed standalone.
Quickapps run on the Vela JS framework, developed by Xiaomi. Building one requires a custom VSCode-based IDE, and documentation beyond the installation guide is sparse to nonexistent.
- Example .rpk with a companion Android sync app — 雷霆元气's Meow Meow eBook
- Vela overview
- Vela IDE download
- Non-Xiaomi Quickapp development docs
Watchfaces and watchface apps are packed into a proprietary .face/.bin format. Two tools exist for creating them, though neither is particularly user-friendly — especially once you want to go beyond static watchfaces and write actual app logic.
While exploring watchface apps I found Sucharek233's SensorTest, which uses Lua and LVGL under the hood — something no public watchface editor exposes or makes editable.
The compression problem
Once I had a handle on the editors and successfully packaged a "Hello, world!" watchface app, I noticed something odd: even with no assets beyond the mandatory watchface preview image, the resulting binary was approaching 0.5 MB. Digging into it, the cause became clear — preview.png was stored uncompressed in RGBA8888. Any other assets would be treated the same way.
I traced this back to the watchface compiler by m0tral bundled with Mi Create. Five minutes with ILSpy was enough to spot the issue: his closed-source compiler v4.22 had added Mi Band 10 support to a DLL bundled inside of the compiler, but hadn't updated the image compression branch — specifically, a missing case in a switch meant compression was simply never applied.
Conviniently, the Telegram handle of the compiler's developer is just m0tral, so I sent him a couple messages. All in all, he expressed no will to help me, nor the community in that matter.
I pulled the DLL out with DnSpyEx, patched it and merged it back into the executable.
Only after succeeding did I get curious enough to check if anyone else has stumbled upon this exact issue themselves. Seems like I was not the first one to question it.
To be continued...
Help build the English-speaking community from scratch — https://discord.gg/ubxwVQZePx
Last modified: Unknown