# Espruino: JavaScript on Microcontrollers With 8kB of RAM

> Espruino runs a JavaScript interpreter on boards as small as 128kB Flash and 8kB RAM, and the repository is also the build system for the official boards. Here is what the code, the Dockerfile and the Makefile actually tell you before you commit a product to it.

**espruino/Espruino** — The Espruino JavaScript interpreter - Official Repo

- Repository: https://github.com/espruino/Espruino
- Website: http://www.espruino.com/
- Stars: 2,976 · Forks: 769
- Language: C
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/espruino-espruino

## What Espruino Solves, and for Whom

Firmware development on a small MCU normally means an edit, a full compile, a flash, and a reset before you learn whether a pin reads the way you expected. Espruino replaces that loop with an interpreter: the README describes it as "a JavaScript interpreter for microcontrollers" designed for devices with as little as 128kB Flash and 8kB RAM. The interpreter lives on the device, so the code you write runs there directly.

The audience is narrow and specific. It is people who already have one of the supported platforms and want to iterate in a scripting language, and people who are building a product on top of the same firmware. The README states that officially supported boards come pre-installed with Espruino and can be flashed with the latest versions easily, and that the documentation on the website matches the version available for download but not the latest version on GitHub. That last sentence matters more than it looks: if you build from master, you are ahead of the documentation.

## The Interpreter, the Board File and the Build

Espruino is not a single binary you configure at runtime. It is a firmware image generated per board. The Makefile comment says to set the BOARD environment variable to the name of a .py file in the boards directory, naming PICO, PUCKJS and ESPRUINOWIFI as examples. So the board definition is a Python file that describes the CPU, the available pins and the connections; from that, the build generates the relevant linker script, headers and documentation.

For an existing architecture, the README says everything can be done from boards/BOARDNAME.py. For a new architecture the work spreads out: boards/pins/*.csv hold pin definition tables copied from the chip datasheet (used by STM32 board files, not required in general, with boards/MICROBIT.py as the counterexample), global build options live in the Makefile, arch-specific Makefile fragments live in make/, processor code in targets/ARCH such as targets/stm32 and targets/linux, and src/jshardware.h acts as the abstraction layer for SPI, I2C and similar peripherals that you implement in targets/ARCH/jshardware.c.

Adding a JavaScript-visible library is a separate axis. The README says to create jswrap_mylib.c/h in libs/ and to look at scripts/common.py for the wrapper conventions. That split is the honest shape of the project: the C side decides what the JavaScript side can even see.

## Building Espruino With Docker or make

The repository ships a Dockerfile whose header comment gives the whole workflow. The image is built from python:3, copies scripts, targetlibs and boards, and runs scripts/provision.sh ALL to install dependencies before copying the rest.

Build the image:

```bash
docker build . -t img_name
```

Then run it with the board you want, which triggers the build inside the container:

```bash
docker run -e BOARD='PICO_R1_3' --name container_name img_name
```

The comment notes that near the end of the build the filename is displayed, for example espruino_2v00_pico_1r3.bin, and that results stay in the container filesystem until you copy them out:

```bash
docker cp container_name:espruino/espruino_2v00_pico_1r3.bin ./
```

The Dockerfile also shows a DFU variant, docker run -e BOARD='BANGLEJS' -e DFU_UPDATE_BUILD=1 --name container_name img_name. Its own comment is blunt about the trade-off: on Linux you should skip the container entirely and "just save yourself gigabytes of downloads and disk space and build Espruino directly".

Direct builds go through make, with BOARD set. The Makefile lists the targets: make for the default binary, make flash to flash with the platform's normal tool, make serialflash for the STM32 USB serial bootloader, make lst for listing files, make boardjson for a board JSON file, make docs for reference HTML, make varsonly to dump variables, and make wrappersources to list the C files that expose functions to the JavaScript environment. Useful switches include DEBUG=1 for symbols, RELEASE=1 to force a release-style compile with no asserts, SINGLETHREAD=1 to make compilation errors easier to find, BOOTLOADER=1 to build the bootloader instead of Espruino, and PROFILE=1 for gprof profiling.

For tests, package.json defines npm test as scripts/factoryTests.js BANGLEJS followed by scripts/factoryTests.js BANGLEJS2, so the default test path is tied to two Bangle.js board definitions rather than being a generic suite. The README points to tests/README.md and to the tests directory for more.

## Where Espruino Is the Wrong Choice

The README is unusually direct about support. It says that while Espruino can run on other boards, the project makes no money from them and cannot afford to test, fix or support the firmware on them, and that it depends on the community. It also states that if your board came pre-installed with Espruino but was not made by the project, you should contact the manufacturer. Ports contributed and then abandoned are moved to the UNMAINTAINED_BOARDS branch, and the README names EFM32 and SAMD as examples of that pattern.

So the failure mode is not a crash, it is a dead end. You pick a board that has a community port, it works well enough for a prototype, and then nobody maintains the target. The README's own framing is that the officially supported boards are the best supported, which is a polite way of saying everything else is your problem.

A second constraint is build surface. A new architecture is not a config change; it is board Python files, datasheet CSVs, Makefile fragments, a targets/ARCH directory and a jshardware.c implementation. If your chip is not already in targets/, budget for porting work before you budget for application code.

Third, memory. The 128kB Flash and 8kB RAM figure is the floor the interpreter is designed for, not a comfortable target. A JavaScript runtime on an 8kB device is a deliberate trade of headroom for interactivity, and the README's Performance Notes link exists because that trade shows up in practice.

## Espruino Against MicroPython and Arduino

The closest comparison people search for is Espruino versus MicroPython. Both put a high-level interpreter on an MCU, so the difference is language and ecosystem rather than concept. Espruino's surface is JavaScript, which means the same syntax you use in a browser or Node, and the project's own topics list espruino-web-ide alongside javascript. MicroPython's surface is Python. If your team already writes JavaScript, Espruino removes a language switch; if your team writes Python, the reverse is true. Neither is a performance argument.

The Arduino comparison is a different axis. Arduino is a compiled C++ toolchain: you write code, compile, and flash a sketch. Espruino keeps an interpreter resident and runs your code on the device, which is why the README can point at a web IDE and a reference of JavaScript commands rather than a sketch upload flow. The cost is that the interpreter occupies the device alongside your program, and the benefit is that you can change behaviour without a full rebuild. For a device that ships to customers and never changes, that trade usually goes the other way.

## Licence and the Cost of Staying Current

The README's licence section does not spell out terms; it says to see the LICENSE file. The package.json declares the licence as MPLv2, and the Makefile header carries the Mozilla Public License, v. 2.0 notice. The README's guidance for anyone selling the software on their own board is explicit: read the terms of the MPLv2 licence and make sure you comply, and note that MPLv2 dictates that any files you modify must be made available in source form. That is a source-disclosure obligation scoped to modified files, and it is the thing to take to whoever handles your licensing, not something to infer from this article.

Upgrade cost is dominated by the board file. Because the firmware is generated from boards/*.py, a new chip revision or a different pinout is a board definition change plus a rebuild, not a patch to a shared binary. The README also warns that website documentation matches the download version and not master, so if you build from Git you are reading documentation written for a different revision. The project publishes automatically built binaries for the Espruino Board and Pico Board for each Git commit at espruino.com/binaries/git, which is the practical way to track master without building it yourself. There are no retrieved releases in the repository metadata, so pinning to a tagged version is not something this material can confirm as a workflow.

## Conclusion

Adopt Espruino if you are prototyping on a supported platform (STM32 F1/F3/F4/L4, nRF52, nRF51, ESP8266, ESP32/ESP32-S3/ESP32-C3, or Linux) and want to type JavaScript at a device without a compile-flash cycle for every change. Do not adopt it if your board is not one of those, or if you need a support guarantee on hardware Espruino sells no boards for; the README says plainly that non-official boards may not get addressed and that community-maintained ports live on the UNMAINTAINED_BOARDS branch. Before you start, open boards/ and confirm a .py file exists for your exact chip and pinout, and read LICENSE because the README points there rather than naming terms itself.

## FAQ

### What is Espruino?

It is a JavaScript interpreter for microcontrollers, designed for devices with as little as 128kB Flash and 8kB RAM, according to the README. The same repository also contains the build system that generates firmware per board.

### How does Espruino compare with Arduino?

Arduino is a compiled C++ sketch workflow, while Espruino keeps a JavaScript interpreter resident on the device so code runs there directly. The README frames Espruino around a web IDE and a JavaScript command reference rather than sketch uploads.

### Can I use Espruino with VS Code?

The README does not document a VS Code integration. It points to the Espruino website, the web IDE topic, the forum, and the Quick Start Guide for official boards instead.

## Sources

- [espruino/Espruino on GitHub](https://github.com/espruino/Espruino)
- [Issues](https://github.com/espruino/Espruino/issues)
- [Project website](http://www.espruino.com/)
- [README](https://github.com/espruino/Espruino/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/espruino-espruino
