A Definitive Guide to Running PicoRuby on ESP32 (ESP-IDF 5.x)

December 18, 2025

Running PicoRuby on an ESP32 is absolutely possible — but today it is not straightforward, and most guides omit critical details. This article consolidates everything that actually matters, based on real-world setup, debugging, and integration with ESP-IDF 5.5.

Article content

If you follow this guide exactly, you will end with:

  • PicoRuby running on an ESP32
  • A working serial shell
  • An interactive Ruby REPL (irb)
  • A correct partition layout
  • A reproducible, clean build

No guesswork. No hacks.

Advertise on RubyStackNews

RubyStackNews is a niche publication read by Ruby and Rails developers worldwide. Our audience includes senior engineers, tech leads, and decision-makers from the US, Europe, and Asia.

Sponsorship Options

📝 Article Sponsorship
Your brand featured inside a technical article (clearly marked as sponsored).
USD 250 per article
📌 Inline Sponsored Block
Highlighted sponsor section embedded within an article.
USD 100 per week
📎 Sidebar Sponsor
Logo + link displayed site-wide in the sidebar.
USD 150 per month
  • Highly targeted Ruby / Rails audience
  • Organic traffic from search and developer communities
  • No ad networks — direct sponsorships only

Interested in sponsoring RubyStackNews?

Contact via WhatsApp

1. Hardware and assumptions

This guide assumes:

  • ESP32 classic (ESP32-D0WD / ESP32-WROOM-32)
  • 4 MB flash (most common)
  • Linux (Debian/Ubuntu-based)
  • ESP-IDF v5.5.x

To confirm your chip:

esptool.py --port /dev/ttyUSB0 chip_id

Expected output:

Chip is ESP32-D0WD (revision v0.0)

2. Install ESP-IDF dependencies (Linux)

sudo apt-get install -y \
  git wget flex bison gperf \
  python3 python3-pip python3-venv \
  cmake ninja-build ccache \
  libffi-dev libssl-dev \
  dfu-util libusb-1.0-0

3. Clone and install ESP-IDF

mkdir -p ~/esp32
cd ~/esp32

git clone -b v5.5.1 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32
Article content

Export the environment (required in every new shell)

. $HOME/esp32/esp-idf/export.sh
Article content

4. Create a project

cd ~/esp32
idf.py create-project hello_world
cd hello_world

5. Add PicoRuby correctly (critical)

❌ What not to do

Do not add PicoRuby inside esp-idf/components. ESP-IDF is the SDK, not your application.

✅ Correct approach (canonical)

From the project root:

cd ~/esp32/hello_world
git init   # if the project is not already a git repo

git submodule add https://github.com/picoruby/picoruby-esp32.git components/picoruby-esp32
git submodule update --init --recursive

Mandatory verification

ls components/picoruby-esp32/picoruby/include

If this directory does not exist, the build will fail. This directory must exist — it is not optional.


6. Configure main/

Project structure

hello_world/
├── main/
│   ├── CMakeLists.txt
│   └── hello_world_main.c
└── components/
    └── picoruby-esp32/

main/CMakeLists.txt

idf_component_register(
  SRCS "hello_world_main.c"
  REQUIRES picoruby-esp32
  PRIV_REQUIRES spi_flash
)

hello_world_main.c

#include "picoruby-esp32.h"

void app_main(void)
{
    picoruby_esp32();
}

7. Set the correct target

idf.py set-target esp32

Important: set-target is always the chip, never the framework or library.


8. Fix the partition table (absolutely required)

PicoRuby + mruby does not fit in the default 1 MB app partition.

Open menuconfig:

idf.py menuconfig

Navigate to:

Partition Table →
  Partition Table →
    Single factory app (large), no OTA

This option is the ESP-IDF 5.x equivalent of “Huge App”.

Why this matters

  • App partition ≈ 2–3 MB
  • OTA disabled
  • Required for PicoRuby / MicroPython
  • Works perfectly on 4 MB flash ESP32

Save and exit.


9. Build

rm -rf build
idf.py build

If you see errors mentioning rake, install Ruby build tools:

sudo apt install -y ruby ruby-dev rake

Then rebuild.


10. Flash and monitor

Article content
idf.py -p /dev/ttyUSB0 flash
idf.py -p /dev/ttyUSB0 monitor

11. Understanding what you see (very important)

You will see a prompt like:

$>

This is NOT Ruby.

This is the PicoRuby shell.

Enter the Ruby REPL

$> irb

Now you are in Ruby.

Example:

irb> puts "Hello from ESP32"
Hello from ESP32
=> nil

irb> 1 + 2
=> 3

12. Mental model (this avoids confusion)

ESP32 boot
   ↓
PicoRuby shell ($>)
   ↓
irb
   ↓
Ruby interactive REPL

This is intentional design, not a bug.


13. What you have achieved

At this point you have:

  • ✅ ESP-IDF 5.5 running
  • ✅ PicoRuby integrated correctly
  • ✅ mruby built for Xtensa
  • ✅ Correct partition layout
  • ✅ Working serial shell
  • ✅ Interactive Ruby REPL on ESP32

This is not trivial, and most guides stop far earlier.


14. Where to go next

From here you can:

  • Embed Ruby scripts in mrblib/
  • Control GPIO, I2C, SPI from Ruby
  • Build a Ruby-driven firmware
  • Ship PicoRuby as a scripting layer
  • Document or productize your setup

Final notes

PicoRuby on ESP32 works well, but today it requires:

  • correct Git submodule handling
  • correct partition sizing
  • understanding that $> ≠ Ruby
  • explicit entry into irb

Once those are understood, the system is stable, powerful, and elegant.

Article content

Leave a comment