| name | boxlang-runtime-esp32 |
| description | Use this skill when deploying BoxLang to ESP32 microcontrollers using MatchBox's --target esp32 flag, flashing firmware (full-flash vs fast-deploy), using watch mode for rapid iteration, accessing hardware via BoxLang BIFs, detecting the ESP32 runtime, and understanding FreeRTOS task constraints. |
BoxLang on ESP32
Overview
MatchBox can compile and deploy BoxLang scripts directly to ESP32 microcontrollers using --target esp32. BoxLang runs on FreeRTOS with a custom task stack, and bytecode is stored in a dedicated flash partition. Full firmware flashing is only needed on first setup; subsequent deploys update only the bytecode (~1 second).
Prerequisites
cargo install espup
espup install
cargo install espflash@3.3.0
First Flash (Full Firmware)
The first deploy installs the BoxLang firmware onto the device:
matchbox app.bxs --target esp32 --chip esp32s3 --full-flash
--full-flash installs the full firmware (bootloader, partition table, and ByteCode VM)
- Only needed on first use or firmware upgrades
- Takes 30–60 seconds
Fast Deploy (Bytecode Only)
After the firmware is installed, subsequent deploys update only the bytecode partition:
matchbox app.bxs --target esp32 --chip esp32s3 --flash
- Updates only the
storage partition at 0x110000
- Takes ~1 second
- No firmware reinstall needed
Watch Mode (Auto-Recompile + Reflash)
Use --watch for rapid iteration during development:
matchbox app.bxs --target esp32 --chip esp32s3 --flash --watch
- Watches
.bxs files for changes
- Automatically recompiles and reflashes on save
- Starts
espflash monitor to show serial output
Supported Chips
| Chip | Flag |
|---|
| ESP32-S3 | --chip esp32s3 |
| ESP32-C3 | --chip esp32c3 |
| ESP32 (original) | --chip esp32 |
| ESP32-S2 | --chip esp32s2 |
FreeRTOS Task Constraints
BoxLang runs as a FreeRTOS task with the following constraints:
| Property | Value |
|---|
| Task stack size | 48 KB |
| Bytecode partition | storage at 0x110000 |
| Partition size | 1 MB |
| CPU | Xtensa LX7 (S3) / RISC-V (C3) |
Keep your BoxLang scripts lean — avoid deep call stacks and large in-memory data structures.
Runtime Detection
Detect ESP32 environment in BoxLang code:
var arch = server.os.arch
if ( arch == "xtensa" ) {
println( "Running on Xtensa ESP32" )
} else if ( arch == "riscv" ) {
println( "Running on RISC-V ESP32" )
} else {
println( "Running on: " & arch )
}
Example Script
var ledPin = 2
gpioSetMode( ledPin, "OUTPUT" )
while ( true ) {
gpioWrite( ledPin, 1 )
delay( 500 )
gpioWrite( ledPin, 0 )
delay( 500 )
}
matchbox blink.bxs --target esp32 --chip esp32s3 --flash
Serial Monitor
View serial output from the device:
espflash monitor
matchbox app.bxs --target esp32 --chip esp32s3 --flash --watch
Flash Partition Layout
0x000000 Bootloader
0x008000 Partition Table
0x010000 BoxLang Firmware (VM + Rust runtime)
0x110000 Storage Partition (BoxLang Bytecode, 1MB)
The --flash flag targets only 0x110000 — no firmware reinstall.
Development Workflow
1. Write BoxLang script (box.bxs)
2. First-time: matchbox box.bxs --target esp32 --chip esp32s3 --full-flash
3. Iterate: matchbox box.bxs --target esp32 --chip esp32s3 --flash --watch
4. Monitor serial output in the watch console
5. Test on desktop before deploying: matchbox box.bxs (interpreted)
Checklist