Open-source project
espressif/esptool avatar
espressif/esptool

esptool: flashing Espressif chips over serial from Python

Serial utility for flashing, provisioning, and interacting with Espressif SoCs

6,503 stars1,499 forksPythonGPL-2.0

At a glance

What is it?
esptool is the Python serial utility Espressif maintains for flashing, provisioning and talking to its SoCs. It is a command-line tool first, with espefuse and espsecure as companions, and it targets developers who own the hardware rather than people looking for a browser or phone app.
Who is it for?
Adopt esptool if you flash Espressif boards from a Linux, macOS or Windows host and want one scriptable tool that also handles eFuses and secure boot keys. Do not adopt it if you want a GUI flasher, a browser page or an Android app, because this repository ships none of those and the README points only at the documentation and esptool -h.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What esptool is for, and who actually needs it

esptool is the serial utility Espressif uses to put firmware onto its chips and to read them back. The README describes it as "a Python-based, open-source, platform-independent serial utility for flashing, provisioning, and interacting with Espressif SoCs", and the package metadata lists POSIX, Windows and macOS as supported operating systems. That combination is the point: the same code path runs on a Linux build server, a developer's Mac and a Windows laptop in a lab.

The tool is for people who have a board on a USB cable. If you are writing firmware in ESP-IDF, esptool is what runs underneath the flash step. If you are bringing up a bare module, it is what tells you which chip you are talking to and what MAC address it carries. The repository also ships espefuse.py and espsecure.py alongside esptool.py, so one install covers flashing, eFuse programming and image signing keys. That grouping matters in production, where the same pipeline that writes the application image also burns the eFuse that locks the bootloader.

It is not an IDE plugin, a graphical flasher or a hosted service. There is a separate documentation site and a --help output, and the README does not promise anything beyond them.

The flasher stub and why the first connection is unusual

The most distinctive mechanism in esptool is the flasher stub. The README states that esptool "uploads a small flasher stub program to the chip to improve flashing performance and work around ROM bootloader limitations", that the stub is developed in the esp-flasher-stub repository, and that prebuilt binaries are bundled with esptool releases.

That gives a two-stage data flow. The host opens the serial port and speaks to the ROM bootloader that every Espressif chip exposes on reset. The ROM loader is small and slow by design. esptool then uploads the stub into RAM and hands over. From that point the stub services the flash operations, which is why large images do not take as long as the ROM loader alone would suggest, and why some operations exist at all despite ROM limitations.

The practical consequence is that the stub is not fetched at runtime. It travels inside the esptool release you installed, so an offline machine can still flash. It also means the bundled stub and the installed esptool version are tied together; a mismatch between the two is not something the README describes a recovery path for.

Installing esptool and flashing your first image

The project is distributed as the esptool package on PyPI. The pyproject.toml declares requires-python = ">=3.10" and classifiers for Python 3.10 through 3.14, so an older interpreter is a hard stop rather than a warning. The dependency list is short but not empty: bitstring, cryptography, pyserial, reedsolo, PyYAML, intelhex, rich_click, click and esp-pylib with the ide, serial and cli extras.

Install it with pip so the console scripts land on a path you control:

bash
pip install esptool

The setup.py defines console_scripts entry points named esptool, espsecure, espefuse and esp_rfc2217_server, and on non-Windows systems it also installs the older esptool.py, espsecure.py and esp_rfc2217_server.py script names for backward compatibility. On Windows those dotted names are added as entry points instead of script files.

Once installed, the first useful command is not a flash at all. The README points at esptool -h for the available options, and the documentation site for the rest. A flash writes a bootloader, a partition table and an application image at explicit offsets, using the write_flash subcommand and the port, chip and baud options that esptool -h lists. Those offsets have to match the partition table you actually built. The README does not publish the offset map; the documentation site does. For the companion tools, run espefuse -h and espsecure -h after installation.

Where esptool stops being the right tool

The clearest limitation is scope: esptool talks to Espressif silicon. It has no path to an STM32, a Nordic part or an AVR, and no generic SWD or JTAG backend. If your product mixes vendors on one line, esptool covers one segment of it.

The second is the interface. Everything here is a command line over a serial port. The related searches show people looking for esptool online, a web version and an Android version; none of those exist in this repository, whose top-level entries are Python modules, docs, CI configuration and tests. Anyone who needs a browser-based flasher is looking at a different class of tool.

The third is host setup, which is where most first attempts fail. The pyproject.toml depends on pyserial, and pyserial talks to whatever serial device the operating system presents. On Windows that means a USB-to-serial driver must already be installed before esptool can see the port; the README does not walk through driver installation, and the documentation is the place that does. On Linux, a user without permission on the serial device will get an access error rather than a helpful message about group membership.

Finally, the flasher stub assumes a working ROM bootloader handshake. A board with a held reset line, a bad crystal or a boot strap pin in the wrong state will not reach the point where the stub matters.

esptool against esptool-js and vendor GUI flashers

The alternative most people meet first is esptool-js, the JavaScript port used by browser-based flashing tools. The difference is architectural, not cosmetic. esptool-js runs in a browser and reaches the chip through the Web Serial API, so it needs a Chromium-family browser, a user gesture to grant the port, and a page that is already loaded. esptool runs as a local process, reaches the chip through pyserial, and fits into shell scripts, Makefiles and CI runners.

That splits the audiences cleanly. A factory operator flashing one board by hand may prefer a browser page with a button. A build pipeline that flashes a hundred boards per shift, or a script that reads the chip ID into a test report, wants a process it can call and parse. The Python tool also carries espefuse and espsecure in the same install, which the browser port does not replace.

Vendor GUI flashers are the other common comparison. They bundle a driver story and a fixed workflow, which helps on a fresh Windows machine. They also hide the arguments, so the same operation is harder to reproduce on a Linux build host. Choosing between them is really choosing whether the flash step should be a button or a line in a script.

Maintenance, releases and the GPL-2.0 licence

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent and versioned in two lines: v5.4.0 on 2026-09-02, v5.3.1 on 2026-06-29, and v4.12.0 on 2026-07-14. The presence of a maintained 4.x release alongside 5.x is worth noting, because it means a project pinned to 4.x is not abandoned, but it also means fixes may land in one line and not the other. Check CHANGELOG.md for which line a given fix belongs to before you upgrade.

Upgrade cost is mostly Python-side. The declared floor is Python 3.10, so a host still on 3.9 blocks the upgrade entirely. Dependencies are pinned loosely with lower bounds and a few exclusions, which means a fresh install can pull newer libraries than your last one did. In an environment where flashing is part of a release process, pinning esptool and its dependency set together is the predictable choice.

The licence is GPL-2.0, and pyproject.toml records it as "GPLv2+" with the classifier "GNU General Public License v2 or later (GPLv2+)". That is a copyleft licence. If you redistribute esptool or a modified version, the licence terms travel with it. Running the tool to flash your own hardware is a different situation from shipping it inside a product, and the boundary between those cases is a legal question rather than a technical one. Read the LICENSE file and, if your distribution model is unusual, get advice from someone qualified to give it.

Editorial conclusion

Adopt esptool if you flash Espressif boards from a Linux, macOS or Windows host and want one scriptable tool that also handles eFuses and secure boot keys. Do not adopt it if you want a GUI flasher, a browser page or an Android app, because this repository ships none of those and the README points only at the documentation and esptool -h. Before you rely on it in a build, verify that your host Python is at least 3.10, that pip pulls a matching esp-pylib, and that your board enters the ROM bootloader reliably at the baud rate you intend to use.

Frequently asked questions

What does esptool do?

It is a Python-based serial utility for flashing, provisioning and interacting with Espressif SoCs, and it runs on POSIX, Windows and macOS. The same installation also provides espefuse and espsecure for eFuse programming and secure boot key handling.

How do I install esptool?

Install the esptool package from PyPI with pip. The pyproject.toml requires Python 3.10 or newer, so an older interpreter will refuse the install.

How do I install esptool on Ubuntu?

The install is the same as on any POSIX host: run pip install esptool, after which the console scripts esptool, espsecure, espefuse and esp_rfc2217_server are available.

How do I use esptool on Windows?

Install the package with pip as usual; setup.py adds the dotted entry points such as esptool.py on Windows for backward compatibility. The USB-to-serial driver must already be installed before esptool can open the port.

How do I flash using esptool?

Use the write_flash subcommand with a chip, a port, a baud rate and one or more offset-and-file pairs, as listed by esptool -h. The offsets have to match the partition table you built; the repository README does not publish the offset map, the documentation site does.

Official sources

  1. espressif/esptool on GitHub
  2. License: GPL-2.0
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/espressif-esptool.svg)](https://hysenlabs.com/projects/espressif-esptool)
Community notes

Community notes