Getting Started
Setup modules
Poco Renderer
Creating Fonts
Moddable One
Moddable Two
Moddable Three
Moddable Four
nRF52 Low Power Notes
Raspberry Pi Pico
M5Core Ink
SiLabs Gecko
Moddable Zero
Adafruit 1.8" ST7735
Adafruit OLED Display
BuyDisplay 2.8" CTP - ESP8266
Crystalfontz ePaper
Generic 1.44"
Generic 2.4" & 2.8" (Resistive Touch) - ESP32
Generic 2.4" & 2.8" (Resistive Touch) - ESP8266
Generic 2.4" & 2.8" (Resistive Touch) - Pico
Sharp Memory
Sharp Memory Screen 1.3"
SparkFun TeensyView
Switch Science Reflective LCD
DESTM32S display
DotStar display
ILI9341 display
LPM013M126A display
LS013B4DN04 display
MCP230XX GPIO expander
SSD1306 display
SSD1351 display
ST7735 display
TLS (SecureSocket)
Web Things
Audio Output
Expanding Keyboard
Die Cut
Using After Effects Motion Data
Defines in Manifests
JavaScript language considerations on embedded devices using the XS engine
Mods – User Installed Extensions
ROM Colors
Using XS Preload to Optimize Applications
XS Conformance
XS Marshalling
XS Platforms
XS in C
XS linker warnings
XS Compartment
XS Profiler

M5Paper Developer Guide

Copyright 2021-2022 Moddable Tech, Inc.
Revised: March 22, 2022

This document provides information about using the M5Paper with the Moddable SDK, including how to build and deploy apps and links to other development resources.

Table of Contents

SDK and Host Environment Setup

To build and run apps on M5Paper, you'll need to:

  1. Install the Moddable SDK
  2. Install ESP32 tools
  3. (macOS users only) Follow the instructions in the macOS section below.
  4. Follow the instructions in the Building and Deploying Apps section below.


The USB driver situation for M5Paper on macOS is a little tricky. You need to:

  • Run at least macOS Big Sur
  • Install the driver referenced in this issue

Building and Deploying Apps

There are several example applications in the Moddable SDK that show how to take make best use of the M5Paper. See the ePaper blog post for details.

After you've set up your host environment and ESP32 tools, take the following steps to install an application on your M5Paper.

  1. Attach the M5Paper to your computer with the USB cable that came with the device.

  2. Build and deploy the app with mcconfig.

    mcconfig is the command line tool to build and launch Moddable apps on microcontrollers and the simulator. Full documentation of mcconfig is available here.

    Use the platform -p esp32/m5paper with mcconfig to build for M5Paper. For example, to build the epaper-photos example:

    cd $MODDABLE/examples/piu/epaper-photos
    mcconfig -d -m -p esp32/m5paper

    The examples readme contains additional information about other commonly used mcconfig arguments for screen rotation, Wi-Fi configuration, and more.

    Use the platform -p simulator/m5paper with mcconfig to build for the M5Paper simulator.


See the Troubleshooting section of the ESP32 documentation for a list of common issues and how to resolve them.

Development Resources

Port Status

The following are implemented and working:

  • EPD display driver
  • GT911 touch driver
  • SHT30 temperature/humidity sensor
  • A / B / C buttons
  • RTC

Note: The I2C address of the GT911 touch controller floats. The implementation tries both addresses 0x14 and 0x5D. This is handled in host provider's Touch constructor -- not in driver and not in user script. If 0x14 fails, an exception is thrown before it retries at 0x5D. If you encounter this, just hit Go in xsbug.

Display Driver

The display driver is a Poco PixelsOut implementation. This allows it to use both the Poco graphics APIs and Piu user interface framework from the Moddable SDK.

While many existing Poco and Piu examples run with the EPD, most are not practical. Because they were designed for a small color LCD with a high refresh rate, their appearance on a big gray display with a low refresh rate is often silly. We need some examples designed for this display.

The display driver is written entirely in JavaScript. It uses Ecma-419 IO APIs for all hardware access. Performance is excellent, often faster than the EPD class built into the native M5Paper library. One reason for this is that Poco can render directly to 4-bit gray pixels, eliminating the need for pixel format conversion. Another reason is that the SPI transfers to the display controller bulk transfer of thousands of pixels at a time, rather than four at a time. This reduces the number of bits transferred by over half.

Memory use is also quite low. There is no frame buffer in ESP32 memory: rendered pixels are sent directly to the display from a 16 line render buffer (about 8 KB).

Using the continue feature of Poco, it is possible to update several areas of the screen while only refreshing the EPD panel once. This allows for very efficient updates -- the least possible amount of memory is transferred and only one long panel flash occurs. The Piu balls example is a good way to see this in action -- only the ball images (not the empty space around them) are transferred to the display and only the rectangle that encloses the four balls flashes on the display panel.

The rotation feature of the display controller is supported, allowing no-overhead rotation at 0, 90, 180, and 270 degree rotations.

Update Modes

The display controller supports several different update modes. The optimal mode depends on the content being drawn. The mode may be changed on each frame. The default mode is GLD16. To change the mode, call the config method of the global screen object. For example:

screen.config({updateMode: "A2"});

You may see artifacts that remain on the screen from previous apps when you install a new app on your device. To get rid of these, it is helpful to draw at least one complete frame in a high-quality mode (e.g. GC16) before switching to a faster update mode (e.g. A2). The epaper-flashcards example does this using a pattern that can be applied to most apps:

onDisplaying(application) {
	screen.configure?.({updateMode: config.firstDrawMode ?? config.updateMode});
	if (config.firstDrawMode)
		application.defer("onFinishedFirstDraw", config.updateMode);
	this.showNextCard(application, 1); // render the initial screen of the app
onFinishedFirstDraw(application, mode) {
	screen.configure({updateMode: mode});

Using this pattern, per-device firstDrawMode and updateMode settings can be applied in the project's manifest.json:

"platforms": {
	"esp32/m5paper": {
		"config": {
			"firstDrawMode": "GC16",
			"updateMode": "A2"

Image Filters

The display driver supports several different pixel filters. These filter adjust the luminance of the pixels. The are useful for optimizing image and applying special effects. The default filter is "none". The filter may be changed on each frame. To change the filter, call the config method of the global screen object. For example:

screen.config({filter: "negative"});

The filters are a Uint8Array of 16 values. To set your own filter, instead of using one of the built-in filters:

let filter = new Uint8Array(16);
// code here to initialize filter


The Moddable SDK has over 150 example apps that demonstrate how to use its many features. Many of these examples run on M5Paper.

That said, not every example is compatible with M5Paper hardware. For example, some examples are designed to test specific display and touch drivers that are not compatible with the M5Paper display and give a build error.

There are several example applications in the Moddable SDK that show how to take make best use of the M5Paper. See the ePaper blog post for details.


All the documentation for the Moddable SDK is in the documentation directory. The documentation, examples, and modules directories share a common structure to make it straightforward to locate information. Some of the highlights include:

  • The commodetto subdirectory, which contains resources related to Commodetto--a bitmap graphics library that provides a 2D graphics API--and Poco, a lightweight rendering engine.
  • The piu subdirectory, which contains resources related to Piu, a user interface framework that makes it easier to create complex, responsive layouts.
  • The networking subdirectory, which contains networking resources related to BLE, network sockets, and a variety of standard, secure networking protocols built on sockets including HTTP/HTTPS, WebSockets, DNS, SNTP, and telnet.
  • The pins subdirectory, which contains resources related to supported hardware protocols (digital, analog, PWM, I2C, etc.). A number of drivers for common off-the-shelf sensors and corresponding example apps are also available.


If you have questions, we recommend you open an issue. We'll respond as quickly as practical, and other developers can offer help and benefit from the answers to your questions. Many questions have already been answered, so please try searching previous issues before opening a new issue.


The best way to keep up with what we're doing is to follow us on Twitter (@moddabletech). We post announcements about new posts on our blog there, along with other Moddable news.