How to Install ESPHome on ESP32: Setup and First Flash
This guide explains ESPHome installation via the Home Assistant add-on, Docker, or pip, then covers ESP32 setup, USB flashing, and bootloader fixes.
The honest answer to how to install ESPHome on ESP32 is that it is two installs, not one. First you put ESPHome itself somewhere: the Home Assistant add-on, a Docker container, or a pip package. Then you use it to compile firmware from a YAML file and push that firmware onto the board. The getting started guide is blunt about the part people try to skip: “The very first install has to happen over a USB cable; every update after that can happen wirelessly.” Below is the shortest path through each hosting option, the config you actually need, and the two things that stall most first flashes: a charge-only USB cable and a board that will not drop into its bootloader.
Who this is for, and who should skip it
You want this if you are building your own sensor, relay or display and you are comfortable editing YAML. Budget an evening for the first device, mostly spent on drivers and cables, and ten minutes for every device after it.
Skip it if you want a temperature sensor that just works. A Zigbee or Thread sensor pairs in a minute and never asks you about frameworks. ESPHome is for people who want to build the device, not just own it.
Pick the hosting option by where Home Assistant runs:
- Home Assistant OS: use the add-on. It is the least friction and it sees USB directly.
- Home Assistant Container, or a separate box: run the Docker image. Add-ons need the Supervisor, so the add-on route does not exist on a Container install; the install method comparison explains that split.
- You want a terminal: pip. Same compiler, no web UI unless you ask for it.
Step 1: install ESPHome three ways
All three come from the official install page. The web UI is now called the ESPHome Device Builder; the compiler underneath is still esphome.
Home Assistant add-on. Open Settings, then Apps, then Install App, search for “ESPHome Device Builder”, then Install, Start and Open Web UI. If the store cannot find it, the add-on repository is https://github.com/esphome/home-assistant-addon.
Docker. The documented one-liner:
docker run --rm --net=host -v "${PWD}":/config -it ghcr.io/esphome/esphome
The dashboard listens on port 6052. The --net=host flag is there for mDNS, which is how the dashboard finds your devices for wireless updates. On Docker Desktop you have to substitute -p 6052:6052 and lose discovery, which the docs say outright. If host networking is new to you, Docker Homelab’s host networking guide covers why it exists and what it costs. To flash over USB from inside the container, the FAQ says to pass the port through with --device=/dev/ttyUSB0. Update later with docker pull ghcr.io/esphome/esphome:stable.
pip. The requirement is Python 3.12 or newer, and the docs add: “Install into a virtual environment if you can. Many Linux distributions now refuse to pip install into the system Python.”
python3 -m venv ~/esphome-venv
source ~/esphome-venv/bin/activate
pip install "esphome-device-builder[esphome]"
esphome-device-builder config
That gives you the same web UI on port 6052, pointed at a config directory. If you only want the CLI, pip install esphome is enough, and pip3 install -U esphome updates it.
Step 2: the ESP32 config
In the Device Builder, click Create device, choose New Device Setup, pick your platform and enter Wi-Fi credentials. On the CLI, esphome wizard office-sensor.yaml asks the same questions. Either way you end up with something close to this:
esphome:
name: office-sensor
friendly_name: Office Sensor
esp32:
variant: esp32
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Office Sensor Fallback"
password: !secret ap_password
logger:
api:
encryption:
key: !secret api_key
ota:
- platform: esphome
What each block is doing, with the rules that bite:
name“may only contain lowercase characters, digits and hyphens” and is capped at 24 characters by default, per the core component docs.friendly_nameis what Home Assistant shows as the device name.variantis the chip family:esp32,esp32s2,esp32s3,esp32c3,esp32c6and so on. The ESP32 platform docs now recommendvariantover the older PlatformIOboardID, which has become optional.flash_sizedefaults to 4MB; set it if your module has more.- The framework defaults to ESP-IDF. The 2026.1.0 changelog lists it as a breaking change: “[esp32] Breaking Change: Change default framework to ESP-IDF”. Arduino is still available as an ESP-IDF component, but ESP-IDF is mandatory on the C2, C5, C6, C61, H2 and P4 variants. Do not add a
framework:block unless a specific component tells you to. !secretpulls fromsecrets.yamlnext to your config. The wifi docs say it is “highly recommended to use secrets” for credentials. Theap:block is a fallback hotspot the device raises when it cannot join your network; it lets you fix a wrong Wi-Fi password without walking the board back to a USB port.- The
apiencryption key is “a 32-byte base64-encoded string”, and the API docs page has a generator for it. Home Assistant will ask for this key when it adopts the device, so keep it. otaneeds theplatformkey since 2024.6.0, per the OTA docs. Older tutorials that show a bareota:will fail validation.
Step 3: the first flash over USB
Two hardware checks before you click anything. The physical connection guide warns that “a power only USB cable that usually comes presupplied with powerbanks won’t work”. Then the driver: the ESP32-DevKitC and most clones carry a USB-to-UART bridge, and the same guide links drivers for the CH34x, CP2102 and PL2303 chips. On Linux the CP210x driver is maintained in the kernel tree according to Silicon Labs, so the board usually just appears; run dmesg after plugging in to find the port name. Windows and macOS may need the download.
From there you have two routes:
Browser. Click Install in the Device Builder and choose to plug the board into the computer you are browsing from. This uses Web Serial, which ESP Web Tools says “is available in Mozilla Firefox, Google Chrome and Microsoft Edge browsers (but not on your iOS device)”. This is also the escape hatch when the machine running ESPHome cannot see USB at all, such as Docker Desktop or Home Assistant in a VM without passthrough: download the compiled binary and flash it from web.esphome.io, which the FAQ notes processes the file locally rather than uploading it anywhere.
CLI. esphome run office-sensor.yaml compiles and then asks whether to upload over the serial port or over the air. esphome logs office-sensor.yaml tails the serial log so you can watch it join Wi-Fi.
When it will not connect
The classic symptom is Connecting....____.... repeating until it times out. That means the chip is not in its bootloader. Espressif’s boot mode documentation states the rule: “The ESP32 will enter the serial bootloader when GPIO0 is held low on reset.” Development boards do this automatically because the flasher “resets ESP32 automatically by asserting DTR and RTS control lines of the USB to serial converter chip”, but the same page notes that some third-party boards omit a capacitor on the EN pin and reset unreliably.
The manual fix is on the DevKitC user guide: “Holding down Boot and then pressing EN initiates Firmware Download mode.” Hold BOOT, tap EN, release BOOT, then start the upload. Boards without buttons need GPIO0 bridged to GND with a wire, and the ESPHome guide adds that you may need to power-cycle between erasing and uploading.
Two more from the FAQ: check that the port name has not changed between unplugs, and try a double-press on reset on boards that expect it. If it browns out mid-flash, the DevKitC guide’s rule applies: power from “one and only one” of the USB port, 5V pin or 3V3 pin.
Step 4: adopt it in Home Assistant
Once the board is on Wi-Fi, Home Assistant “can be auto-discovered” and shows the device as Discovered on the Integrations page, per the ESPHome integration docs. Click it and paste the encryption key when prompted; the field is noise_psk if you are adding it by hand. If nothing appears, add it manually by hostname, office-sensor.local, then work out why mDNS is not crossing; a Docker install without host networking and a VLAN boundary are the usual causes.
One quirk worth knowing: the API component has a reboot_timeout that reboots the device after 15 minutes without a client connection, because sometimes the ESP reports itself connected when it is not. If you are running a board without Home Assistant attached, set it to 0s.
After adoption, every change is the same loop: edit the YAML, click Install, choose Wirelessly. The USB cable goes back in the drawer until you brick something. If you are still deciding what should run Home Assistant itself, the hardware guide covers the hub side.
Related across the network
- A $200 N100 Homelab: 11 Services, ~8W Idle, Low Maintenance — minilabhq.com
- Best Docker Containers for Your Home Server in 2026 — dockerhomelab.com
- Best Mini PC for a Docker Homelab in 2026: 3 Tiers Compared — dockerhomelab.com
- Best NAS for Docker Containers in 2026: Synology, QNAP, DIY — dockerhomelab.com
- Docker Compose in 20 Minutes: Your First Self-Hosted Stack — dockerhomelab.com
Sources
- Install ESPHome (ESPHome docs)
- Getting Started with ESPHome and Home Assistant (ESPHome docs)
- ESP32 Platform (ESPHome docs)
- ESPHome 2026.1.0 changelog
- Native API Component (ESPHome docs)
- OTA Update Component (ESPHome docs)
- Frequently Asked Questions (ESPHome docs)
- Physically Connecting to your Device (ESPHome docs)
- Boot Mode Selection (esptool docs, Espressif)
- ESP32-DevKitC V4 User Guide (Espressif)
- ESP Web Tools
- ESPHome integration (Home Assistant docs)
- CP210x USB to UART Bridge VCP Drivers (Silicon Labs)
Related
Home Assistant OS vs Container: Which Install Method to Pick
Home Assistant OS and Container are the only supported installs since 2025.12. How add-ons, backups, USB radios, and update effort decide which you pick.
Home Assistant Hardware: What to Run It On
Green, Yellow, Raspberry Pi, mini PC or a NAS virtual machine. What each Home Assistant hardware route costs you in setup, radios and storage life.
Best Zigbee Coordinator Stick for Home Assistant: 4 Picks
Home Assistant Connect ZBT-2 suits ZHA, while SONOFF and SMLIGHT coordinators offer options for Zigbee2MQTT, Docker, and difficult server locations.