ESP32-S3
An app fault returns to Home; the shell keeps running. An unreadable shell.mbc aborts boot — there is no native fallback yet.
Architecture · the map
Micro OS is an application layer, not a kernel. It owns the app contract — bytecode, execution, UI, host boundary and lifecycle — and delegates threads, memory, drivers and the event loop to the platform underneath.
Five stages. Only the last one knows what a pixel is.
Restricted TypeScript: state, bind, ui.mount and host calls declared in the SDK.
const count = state(0)SWC parses; the allow-list rejects unsupported syntax with a stable MTS code.
path:line:column · MTS002Constants, state, handlers, UI, host descriptors and manifest behind a CRC-32.
MBC1 · v28 · CRC-32Decode, validate, mount once, enqueue events, run handlers, emit patches.
FIFO · one event per tickLVGL objects on metal and macOS, DOM nodes in the browser.
RenderPort · patchesThe dependency rule is one-way: platform code never enters the contract or the core.
| Layer | Crate | Responsibility | Platform dependency |
|---|---|---|---|
| Contract | micro-ir | MBC model, codec, CRC-32, structural validation, icon catalog | None |
| Execution | micro-vm · micro-core | Typed stack machine, event queue, state, bindings, UI tree, patches | None |
| Lifecycle | micro-os-core | Host-independent boot, setup, launcher, app session and Wi-Fi reducer | None |
| Toolchain | micro-compiler · sdk | SWC parse, allow-list diagnostics, lowering, microc CLI, editor types | None |
| Services | micro-store · micro-json · micro-net | Scoped KV/files, path sandbox, JSON queries, HTTP envelope and transport | None |
| Render | micro-lvgl · micro-renderer-web | Map the shared tree and patches to a narrow native or DOM port | None at test time |
| Hosts | micro-host-sdl · micro-host-esp32 · micro-host-web | Own the platform loop, input, timers, Wasm boundary and host services | SDL3 · ESP-IDF · web-sys |
The compiler is a development-host tool. Firmware never compiles TypeScript on the device. The runtime is a library: it does not own a thread, a window or a timer. Each host drives it from its own event loop.
That split is what makes the test suite meaningful. The MBC round trip, VM semantics, binding dependencies and compiler diagnostics can all be tested without a display, a board or a browser.
micro-ir, micro-vm and micro-core have no platform dependencies. If a behavior differs between hosts, the bug is in a host adapter, not in the contract.The host owns time. The runtime owns what happens inside one event.
Wi-Fi connect/disconnect, os.launchIndex, os.goBack.
If the Wi-Fi state changed, re-evaluate the bindings that read it.
The host updates the Wi-Fi icon and SSID; the bar owns its own clock.
Edge swipe and the BOOT button become back/navigation intents.
micro_runtime_tick processes one event, then the host loops until the queue is empty.
Dirty bindings produce patches; the renderer updates existing objects.
Every handler has a default budget of 10,000 instructions. A handler that exceeds it stops. Writes completed before exhaustion remain committed, and dirty bindings are still flushed, so UI and state stay consistent.
Later events remain processable. The queue is not poisoned by one runaway handler, and the host can recover without rebooting the device.
This is a failure boundary, not a scheduler. Micro OS has no background apps, timers, IPC or preemption; one app is in the foreground and all app work runs on the host's UI thread or task.
A manifest declares categories. The compiler checks the call site; the runtime gates the boundary again.
| Capability | Calls | What the host provides |
|---|---|---|
clock | clock.now | SNTP wall clock on device |
kv | kv.get / set / remove | Per-app namespaced state |
config | config.get / set | Human-editable app config |
storage | storage.* | Sandboxed TF-card files |
net | net.http / wifi / lookupWords | Async, callback-delivered |
audio | audio.* | URL playback + speech rate |
json | json.getText / getNumber | Path queries over responses |
device | device.* | Board identity, light, GPIO |
os | os.launch / goBack / setTitle | Shell and chrome control |
Omitting capabilities — or writing an empty list — denies every host call. Under-declaring fails the build with MTS002 rather than failing at first launch.
The gate is per category, not per function: declaring net permits HTTP and Wi-Fi calls. Finer grants are future work. All four shipped apps declare exactly what they use.
One app fault should not take the machine down. The policy differs by host, because the platforms differ.
An app fault returns to Home; the shell keeps running. An unreadable shell.mbc aborts boot — there is no native fallback yet.
Report the fault and keep the process alive. The window loop and the other apps stay up.
Stop the frame loop and surface the error. A reload creates a fresh runtime; KV survives.
An application layer with deliberate boundaries — not a kernel, not a browser, not a marketplace.
ui.mount; there is no runtime widget creation or unbounded list.macOS and the browser are supported today. ESP32-S3 is the reference device. Windows and Linux native builds are source-level groundwork; native iOS and Android are out of scope.
These boundaries are not accidents. The project would rather ship a small contract that is tested end to end than a broad one that only works on the demo machine.