Moddable SDK moves to ESP‑IDF 4.2. Brings modern JavaScript to ESP32‑S2 powered Kaluga and Saola boards.

Note: This blog post was originally posted on January 5, 2021 to introduce the developer preview of ESP-IDF 4.2 support in the Moddable SDK. That development work was merged to the main Moddable SDK repository on February 2, 2021. The blog post has been updated to reflect that.

The Moddable SDK has migrated to using the ESP-IDF 4.2 for all devices powered by Espressif's ESP32 silicon, including our Moddable Two and M5Stack products. ESP‑IDF 4.2 is the latest supported release of board support software from Espressif. This version of the ESP‑IDF allows the Moddable SDK to run on the new ESP32‑S2 silicon, which has both cost and performance benefits for many projects.

This release brings the XS JavaScript engine, the only modern JavaScript engine designed for resource constrained devices, to powerful new low-cost hardware from Espressif Systems. Espressif describes their ESP32-S2 MCU as "[providing] the optimal HMI solution for touchscreen and touchpad-based devices." The easiest and most powerful way to develop rich user experiences for these microcontrollers is in JavaScript using graphics modules in the Moddable SDK.

Migrating to ESP‑IDF 4.2

ESP‑IDF 4.2 is the latest supported version of the board support software by Espressif for their ESP32 family of microcontrollers. While not significantly different in function from the 3.x versions, there are changes to both the build process and APIs that make the transition somewhat challenging. Espressif improved the set-up process in ESP‑IDF 4.2 and, in some cases, also improved build speed. In our tests, the memory use and code footprint are about the same between ESP‑IDF 4.2 and 3.3.2.

Because of the better developer experience, support for more silicon targets, and API differences, support for ESP‑IDF 3.3.2 has been removed from the Moddable SDK.

Developers using the JavaScript APIs provided by the Moddable SDK should not need to make any changes to their code as part of this migration.

Getting Started

Support for ESP‑IDF 4.2 is available in the Moddable SDK repository. The latest instructions to install and update are in the Moddable SDK's ESP32 documentation.

ESP32‑S2 microcontroller

Beyond staying up to date with the latest software from Espressif, adding support for the ESP32‑S2 microcontroller is a major reason for updating to ESP‑IDF 4.2. ESP‑IDF 3.x does not support these relatively new microcontrollers.

The ESP32‑S2 is a variant of the ESP32. It is lower cost and uses less power. In addition, it offers higher SPI performance which is great for displays. The ESP32‑S2 omits some important capabilities of the original ESP32 including a second CPU core, Bluetooth LE support, and about 160 KB of RAM.

Just about all features of the Moddable SDK on ESP32 are supported on ESP32‑S2, except where the hardware support is unavailable. The supported features include Wi-Fi and networking, graphics and displays, and hardware pin control. Web Workers are still supported for multi-threaded execution, but all workers run on the single CPU core. While there is less free memory available, all the examples in the Moddable SDK still run on ESP32‑S2.

Saola and Kaluga development boards

The Saola and Kaluga development boards from Espressif are both powered by the ESP32‑S2 MCU. They are the easiest way to try out the ESP32‑S2 today. This Moddable SDK developer preview supports both.

The Saola is a minimal board with a single button for input and a single LED to display status. The Kaluga board is actually a stack of boards with a variety of I/O capabilities including a QVGA display. The Saola is available in two variations -- the WROOM base model and the WROVER which adds 2 MB of external RAM.

To build for Kaluga and and Saola development boards, use their platform identifiers with mcconfig: esp32/saola_wroom, esp32/saola_wrover and esp32/kaluga.


The display on Kaluga is supported. Note that the Kaluga originally shipped with an ILI9341 display controller which runs at 40 MHz and now ships with an ST7789 display controller which runs at 80 MHz. The two display controllers are functionally equivalent but require different configuration. The Kaluga target in the Moddable SDK is configured for the ST7789. If you have an older board with the ILI9341, reduce the "hz" setting from 8000000 to 4000000 and remove the "ili9341" block from the "config" section of $MODDABLE/build/devices/esp32/targets/kaluga/manifest.json. (Yes, it seems wrong to remove the ILI9341 block to switch to the ILI9341 chip. Both the ILI9341 and ST7789 display controllers use the same ILI9341 driver. What you are doing is removing the configuration for the ST7789 controller which causes the driver to revert to its default settings for the ILI9341.)

Color LED

The Kaluga and Saola boards have a programmable NeoPixel LED. This can be used to show status in color. The Host for these boards allows your code to use the LED as a simple on/off LED:

let led = new Host.LED;

You can also use the Host.LED class to set the LED color because it is an instance of the NeoPixel class:

led.setPixel(0, led.makeRGB(255, 0, 0)); // red

The host has an option to automatically animate the LED in rainbow colors. You can enable that in your project manifest:

"config": {
    "led": {
        "rainbow": true


Both the Saola and Kaluga boards have a button that is used to force the ESP32‑S2 into programming mode on reset. This button is labeled Boot or Flash. Your script can be notified when this button is pressed.

new Host.Button.Flash({
    onPush(pushed) {
        trace(pushed ? "down\n" : "up\n");

The Kaluga also has an array of six buttons. These are cleverly implemented using a single analog input. While the hardware and software implementations are entirely different from the digital Flash button, the JavaScript API is the same. The buttons are available as A to F. The new kaulga-buttons example shows how to use both the touch pad buttons and push buttons.

new Host.Button.B({
    onPush(pushed) {
        trace(pushed ? "B down\n" : "B up\n");

About Host

The platform support for the Kaluga and Saola development boards in the Moddable SDK provide a global Host instance. This is how, for example, you access the LED and buttons as described above. This Host instance is based on the design created by the Ecma TC53, ECMAScript Modules for Embedded Systems. Specifically, the Host here is an example of the Host Provider Instance. During 2021, the Moddable SDK will adopt additional portions of this emerging standard and apply it to more development boards.

More memory with external PSRAM

The ESP32 and ESP32‑S2 have the ability to use external RAM. While the built-in memory is enough for many projects, some do require more. This is particularly important for the ESP32‑S2 which has less built-in memory than the ESP32.

Both the Kaluga and Saola WROVER boards have 2 MB of external PSRAM. This RAM is enabled by the Moddable SDK when building for these targets. It works well. You can now allocate a bigger JavaScript virtual machine. For example, this manifest fragment allocates a 1 MB virtual machine:

        "creation": {
            "static": 1048576

Support for large virtual machines on ESP32 using XS is new, so we are still learning about how to use it best. Keep in mind that PSRAM is significantly slower than the built-in memory. Projects that require PSRAM may run more slowly. Additionally, the larger the memory heaps, the longer it takes for the garbage collector to run. A larger than necessary heap may lead to less frequent garbage collections that block longer. This may not be an issue for networking code but could be a problem for real-time animation.

Finally, the technique used to enable PSRAM on the ESP32‑S2 boards is through an SDKCONFIG fragment. This same approach should work, perhaps with different configuration values, for other boards including those based on ESP32.

Faster graphics with higher SPI throughput

The ESP32‑S2 doubles the speed of the SPI bus to 80 MHz over the 40 MHz of the ESP32. This allow high speed displays to render faster. To take full advantage of the higher-speed output required changes to the implementation of SPI in the Moddable SDK. The SPI output has been rewritten as a small FreeRTOS task which allows transactions to be prepared outside the SPI interrupt. This keeps the delay between SPI buffers to a minimum, helping to maximize throughput.

On the Kaluga board, we are seeing full screen color fill updates at over 60 FPS, which is rendering and transmitting over 76 Mbps per second to the display. This is achieved without use of PSRAM or a full frame buffer in memory. On Moddable Two, running on the 40 MHz ESP32 SPI bus, we now achieve over 30 FPS in the same test, which is nearly 38.7 Mbps. This is the test script using the Poco renderer:

const render = new Poco(screen, {pixels: screen.width * 32});

Timer.repeat(() => {
                render.makeColor(Math.random() * 255,
                Math.random() * 255, Math.random() * 255),
                0, 0, render.width, render.height);
}, 16);

Optimizing throughput requires more RAM to reduce the number of SPI transactions. By default, the Moddable SDK SPI is configured for lower performance (by 5 to 10%) to preserve RAM. In your project manifest, you can tune performance by configuring the number of active SPI transactions and their maximum size. The full screen fill timing tests described above were run with the following settings:

        "defines": {
            "spi": {
                "esp32": {
                    "transactions": 3,
                    "transactionSize": 4096


This release brings together many important new capabilities for developers working with the Moddable SDK on ESP32. It updates the ESP‑IDF to the latest version, providing a simplified install and faster builds as well as support for the ESP32‑S2 microcontroller. It delivers the ability for developers to work with virtual machines that are 10x larger than before, and provides significantly accelerated rendering.

Our thanks to the many members of our community who tried out the ESP-IDF 4.2 support while it was available as a developer preview. Your feedback contributed to making this a better release for everyone.