Ports
A port is the C code that sits under the VM for one chip family: startup, memory map, USB or UART, and the machine bindings. A board is a pinout and a set of compile flags inside that port.
Official ports
| Port | Chips | Notes |
|---|---|---|
| rp2 | RP2040, RP2350 | Pico, Pico W, Pico 2. UF2. Strong machine. |
| esp32 | ESP32, S2, S3, C3, C5, C6, P4 | Wi-Fi / BLE. IDF based. |
| esp8266 | ESP8266 | Small heap. Feature level is tight. |
| stm32 | STM32 F0–U5 and friends | pyboard origin. USB CDC. CAN in 1.28. |
| samd | SAMD21 / SAMD51 | Many Adafruit-shaped boards. |
| nrf | nRF51 / nRF52 | micro:bit, BLE-heavy boards. |
| mimxrt | i.MX RT | Teensy 4 class, lots of RAM. |
| unix / windows / webassembly | Host OS / WASM | No GPIO. Language + stdlib + embed. |
| alif, cc3200, renesas-ra, zephyr, qemu, embed, … | Various | See Other. Tiers in 1.27+ say how complete they are. |
Adding a board
Inside an existing port you usually add a directory under boards/:
mpconfigboard.h— board name, heap size, which peripherals to compilempconfigboard.mkor CMake fragments — CPU variant, linker scriptpins.csvor equivalent — named pins forPin("LED")- Optional
manifest.py— frozen modules baked into the image
A new chip family is a new ports/foo/: main.c, mpconfigport.h, a UART for the REPL, a heap, and then machine bindings one class at a time. The developer docs walk through it; embed is the smallest “port” if you only want the VM inside another program.
Tiers
From 1.27 the project labels ports by how complete and how well tested they are. Tier 1 is the daily-driver set (rp2, esp32, stm32, unix, …). Lower tiers still run; they may lag on machine APIs. Check the release notes when a class is missing — it may be the port, not your script.