App Store & online updates
Firmware 4.2.6 can reach the network directly. Two screens use that: App Store, which browses and installs published apps over Wi-Fi with no manual SD card handling, and Settings → Firmware Update → Online Update, which fetches new firmware the same way. Both are built on top of the same on-device engines the SD-card versions of these features already used — nothing about how an app installs or how firmware flashes changed, only how the file gets onto the card in the first place.
What you need
- The device connected to Wi-Fi (Settings → Connections → WiFi).
- For firmware updates specifically: the one-time USB recovery-partition install already completed (
tools/install_ota_recovery.ps1). Online OTA refuses to proceed without it — see Firmware update & recovery.
Nothing else. There's no account or pairing step on the device side; the catalog is public.
Browsing and installing apps
Open App Store from the main menu. An animated loading screen remains responsive while the device fetches the live catalog from esp32dooms.day. The catalog is a four-row vertical list sized specifically for the 128 × 128 screen. Each row shows:
- the app's icon, loaded in the background while you keep browsing (an animated spinner holds its place until it is ready);
- a readable name and category instead of a shortened grid label;
GET,UPDATE, orREADY, so install state is explicit rather than color-only;- a gold sparkle when the developer or store team has marked it Featured.
Use UP/DOWN or LEFT/RIGHT to move through the list and press SELECT to open a full-screen detail view. The list has no fixed catalog-size limit. Firmware keeps the visible 16 entries plus the previous and next 16-entry pages in a rolling cache. Those neighbors load before you reach them: crossing a page boundary never opens another loading screen, clears the current rows, or exposes page loading/unloading. If a background request fails, the visible list stays usable while the device retries quietly. The counter remains a catalog-wide position such as 25 of 54, and moving past either end still wraps around normally. The detail view shows the icon, name, version, category, package size, wrapped store summary, and only the actions that apply:
- Install if you don't have it yet;
- Update if you do and a newer version is published, or a disabled Current label if not;
- Remove if it's installed.
Navigate between available actions with the D-pad and press SELECT to activate the highlighted one. Choosing Install or Update opens a dedicated transfer screen: phase, progress bar, percentage, byte count, and power warning each have their own row. The package installs automatically after the download finishes and passes its integrity check. If the catalog cannot load, Retry repeats the request without making you leave the App Store.
Catalog pages and icons share one serialized network queue with background weather work. This avoids competing TLS sessions on the ESP32. During a brief Wi-Fi reconnect, already-cached rows remain on screen and browsing can continue; only an uncached icon keeps its small spinner until the connection returns.
Uninstalling from the App Store asks for confirmation first, exactly like uninstalling from Apps, and removes the same things: the installed payload, private key/value data, and the saved-game blob for that app. It never touches anything on your SD card outside what that install put there.
What actually happens on download
The device downloads straight to a scratch file on the SD card, verifying the transfer's SHA-256 hash against the value the catalog reported before handing it to the same install engine File Manager uses for a manually-copied .eft. If the hash doesn't match, or the connection drops, the partial file is discarded and nothing is installed — a failed online install can't leave a corrupt app behind.
Updating firmware online
Open Settings → Firmware Update. Online Update is the first and default option; From SD Card remains directly below it. Selecting Online Update immediately starts an animated, non-blocking check against the latest stable release on esp32dooms.day.
- If you're current, the wrapped status confirms that the installed firmware is up to date and nothing is downloaded. Again checks another time.
- If the check fails, the error wraps inside the result card and Retry repeats it.
- If a newer version exists, the device shows the version, wrapped release title, and download size. Confirming opens a dedicated download screen where the progress bar, percentage, transferred size, and power warning cannot overlap. The
.binlands in/OTA-Firmware-Update/on the SD card — the exact folder the manual SD-update path already uses — and then hands off to the normal update flow: the independently-bootable recovery partition validates the image and installs it, the same way it would for a file you copied there yourself.
That's the whole design: online OTA is a network step bolted onto the front of the existing, already-safe SD-staged updater, not a separate flashing mechanism. Everything in Firmware update & recovery about interrupted updates, the recovery partition, and what to do if a flash goes wrong still applies exactly as written, regardless of which path put the .bin in that folder.
For developers: how apps get into the catalog
Publishing goes through the website, not a device-side upload. Submit a build through the developer portal; once a maintainer approves it, it's live in the public catalog and every device's App Store picks it up on its next visit to that screen — nothing to push, no per-device registration.
The device talks to a small, deliberately narrow public API:
| Endpoint | Purpose |
|---|---|
GET /api/apps?page=N&limit=L | Zero-based catalog page containing name, slug, version, category, summary, size, SHA-256, and featured status, sorted by Featured, publish time, and a unique tie-breaker. The response also reports page, pageSize, offset, total, pageCount, hasPrevious, and hasNext. limit is at most 24 to bound one ESP32 allocation; there is no total-catalog limit. A request without parameters defaults to the first 24 entries for older firmware. Icon pixels remain a separate per-app request. |
GET /api/apps/{slug}/icon | One app's icon, already encoded in the same binary sprite format (DSI1) the firmware uses everywhere else — no separate decoder needed on-device. |
GET /api/apps/{slug}/download | The published .eft package itself. |
GET /api/firmware?channel=stable | The latest firmware release on a channel, chosen by comparing version numbers rather than publish dates, so a corrected re-release still wins even if it went out later. |
GET /api/firmware/{version}/download | That release's .bin. |
All of it is served over TLS, and the device pins the connection to Let's Encrypt's root certificate specifically for these calls — a stricter check than the plain HTTPS the weather-forecast widget uses, because what comes back here gets installed or flashed. Every download is verified against its published SHA-256 before it's trusted, on top of TLS.
If you're building an app to publish, App & game development covers the packaging format and API this catalog ultimately distributes; this page is only about how a finished, approved package reaches a device.
Next steps
- Getting started — the first-boot walkthrough, including where the App Store fits into installing your first app.
- Firmware update & recovery — what the recovery partition actually does once a
.binlands in/OTA-Firmware-Update/. - App & game development — build and package what you'll publish here.