ESP32-S3
A real handheld: 8 MiB flash, 8 MiB PSRAM, an 800 × 480 RGB panel and GT911 touch. LVGL renders the same UI tree the browser does.
- ESP-IDF + FreeRTOS
- LVGL 9.5
- TF card apps
Platforms · three hosts
The same compiled app, the same runtime, three different machines. Hosts own the window, the event loop and the pixels; the app contract stays identical.
Each host implements the same narrow port. They differ in platform services, not in app semantics.
A real handheld: 8 MiB flash, 8 MiB PSRAM, an 800 × 480 RGB panel and GT911 touch. LVGL renders the same UI tree the browser does.
SDL3 owns the window and event loop; the shared Rust runtime executes MBC and LVGL paints it. Apple Silicon is the tested target.
The same runtime compiled to WebAssembly, rendering DOM instead of LVGL. No JavaScript app runtime and no embedded JS engine.
An ESP32-S3 Touch LCD 7: enough flash, PSRAM and pixels to run a real app contract.
| SoC | ESP32-S3 · 8 MiB flash · 8 MiB PSRAM |
| Display | 800 × 480 RGB565 · 16 MHz |
| Touch | GT911 capacitive controller |
| Expander | CH422G · reset / backlight / SD chip select |
| Storage | TF card over SPI · MOSI 11 · MISO 13 · SCLK 12 · CS EXIO4 |
| Input | BOOT button on GPIO0 · edge-swipe back gesture |
| Console | UART0 · 115200 baud |
| Partitions | factory app 0x10000 / 0x3D0000 · micro_app 0x3F0000 / 0x3F0000 |
| Kernel | ESP-IDF 5.5 + FreeRTOS (owned by the platform) |
The board is a host, not a target abstraction. The runtime does not know it is on a microcontroller: it receives a UI tree and a render patch, and the LVGL adapter paints it.
A missing TF card is a warning, not a boot failure. Without a card, storage.available() is false,/apps is ignored, and the built-in apps still launch.
The wall clock is SNTP-backed through micro_clock; before the first sync, clock.now() falls back to uptime.
Ten steps from power to a running shell. No JS engine, no parser, no package manager.
8 MiB flash / 8 MiB PSRAM class check; abort on mismatch.
RGB LCD, GT911 touch and CH422G expander; enable the backlight.
A missing TF card warns; it does not stop boot. storage.available() reports it.
Draw, mark the board profile healthy, clear for the shell.
BOOT button, Wi-Fi STA, KV, SNTP clock, OS reducer.
BOOT_SAMPLED … SETUP_SKIPPED; first-run setup is skipped in this slice.
Raw micro_app partition, up to 8 manifests beside the shell.
Top-level /apps/*.mbc, malformed images skipped, built-in ids win collisions.
Destroy any previous runtime, load shell.mbc into PSRAM, create its Runtime.
Install the host app bar; create the 30 ms LVGL timer that drives the runtime.
What is tested, what is groundwork, and what is deliberately out of scope.
| Target | Status | Notes |
|---|---|---|
| macOS native (SDL/LVGL) | Supported | Apple Silicon is the tested target. |
| Web browser (Wasm/DOM) | Supported | Desktop and mobile, with a responsive simulator. |
| ESP32-S3 reference board | Supported | 800 × 480 RGB panel, 8 MiB flash + 8 MiB PSRAM. |
| Windows / Linux native | Groundwork | Portable SDL layer exists; no packaged launcher, not verified on real desktops. |
| Native iOS / Android | Out of scope | No host or packaging layer. Mobile browser access works through the Web Player. |