Aziz Bench

Getting started with ESPHome

ESPHome turns a short YAML file into firmware for an ESP32 or ESP8266 and connects the board to Home Assistant, without writing C++. This guide goes from installing ESPHome to a temperature, humidity and pressure sensor on your dashboard, with every line of the configuration explained.

By AzizPublished 11 min read

Checked on 4 November 2026 against ESPHome 2026.10.2, the current release: every configuration in this guide passes esphome config on that version. Menu names follow the ESPHome and Home Assistant documentation of the same date.

What ESPHome is

You describe the device in a YAML file: which board, which sensors on which pins, how it reaches your network. ESPHome turns that description into firmware, compiles it and installs it on the board. Home Assistant then talks to the device over ESPHome’s native API, a direct connection on TCP port 6053 that can be encrypted with a 32-byte key.

YAMLyour device fileESPHomebuilds firmwareESP32your boardHome Assistantdashboardfirst: USB cablethen: over Wi-Fiencrypted APIYAMLyour device fileESPHomebuilds firmwareESP32your boardHome Assistantdashboardfirst: USB cablethen: over Wi-Fiencrypted API
From a YAML file to a device in Home Assistant. The first install needs a cable; after that, updates go over Wi-Fi.

There is no code to write for the usual parts. When you change the YAML, you install again and the device runs the new firmware.

Installing ESPHome

The tool you work in is called the ESPHome Device Builder: a web dashboard that keeps your YAML files, compiles them and installs the firmware. Pick one way to run it:

  • In Home Assistant. Go to Settings → Apps → Install app, find ESPHome Device Builder, then click Install, Start and Open Web UI. Home Assistant now calls its add-ons “apps”; if the app is missing, add the repository https://github.com/esphome/home-assistant-addon from the ⋮ menu.
  • As a desktop app. The install page offers ESPHome Device Builder for macOS (a .dmg), Windows and Linux (a .deb or an AppImage). On Linux, add yourself to the dialout group if serial ports don’t show up.
  • In Docker. The same dashboard listens on port 6052. Run the container with host networking (--net=host) so it can find devices by mDNS; with Docker Desktop, publish port 6052 instead.
  • On the command line. Run pip install esphome (in a virtual environment if you can); then esphome run living-room.yaml validates, compiles, installs and shows the logs in one go.

For the very first flash you can also use ESPHome Web at web.esphome.io, which writes firmware to a board straight from the browser. It needs Web Serial: Chrome, Edge and, according to the ESP Web Tools documentation, Firefox; not iOS.

Choosing a board

Any ESP32 or ESP8266 development board will do. These four are common, cheap and well supported; the board ID is what goes in the YAML.

BoardYAMLGood forPins
ESP32 DevKitesp32: board: esp32devMost tutorials and examples, plenty of pinsESP32 pinout
ESP32-C3 SuperMiniesp32: board: esp32-c3-devkitm-1Tiny, cheap, low-power sensorsC3 SuperMini pinout
ESP32-S3 DevKitC-1esp32: board: esp32-s3-devkitc-1More memory, native USB, cameras and displaysS3 DevKitC-1 pinout
Wemos D1 miniesp8266: board: d1_miniSimple sensors and relays on an older, smaller chipD1 mini pinout

Board IDs checked with esphome config on ESPHome 2026.10.2. Our ESP32 comparison lists the differences between the chips.

If you are unsure, start with an ESP32 DevKit: this guide uses one, and most answers you will find online assume one.

A first configuration, line by line

In the Device Builder, Create device starts a wizard that writes most of this for you. Here is the whole file for a device called living-room, before any sensor:

esphome:
  name: living-room            # host name: lowercase, digits, hyphens
  friendly_name: Living room   # the name Home Assistant shows

esp32:
  board: esp32dev              # your board
  framework:
    type: esp-idf              # the default since 2026.1

logger:                        # log over USB and Wi-Fi

api:                           # the link to Home Assistant
  encryption:
    key: !secret api_key

ota:
  - platform: esphome          # updates over Wi-Fi
    encryption:                # reuses the API key

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:                          # fallback hotspot
    password: !secret ap_password

captive_portal:                # its setup page
  • esphome: → name is the host name on your network, living-room.local: up to 31 characters, lowercase letters, digits and hyphens. friendly_name is what Home Assistant displays.
  • esp32: → board tells ESPHome the chip and its flash size. Since ESPHome 2026.1 the framework defaults to ESP-IDF on the ESP32; writing it out keeps the file clear. Arduino is still supported with type: arduino.
  • logger: → logs over USB and over the network, at DEBUG level and 115200 baud by default.
  • api: → the native API that Home Assistant uses, with its encryption key. Without a key the connection isn’t encrypted.
  • ota: → updates over Wi-Fi. Since ESPHome 2026.9 an empty encryption: encrypts them with the API key.
  • wifi: → your network, read from secrets.yaml. ap: starts a fallback hotspot, named after the device, if it can’t connect within 90 seconds.
  • captive_portal: → a page on that hotspot where you can enter new Wi-Fi details.

The !secret values come from a second file, secrets.yaml, in the same folder:

wifi_ssid: "MyNetwork"
wifi_password: "MyWiFiPassword"
api_key: "…"                   # openssl rand -base64 32
ap_password: "…"

The API key is 32 random bytes in base64: the wizard makes one, or the command in the comment does. Keep secrets.yaml out of anything you publish.

A first sensor: BME280 over I²C

A BME280 measures temperature, humidity and pressure and talks over I²C, so it needs two signal wires. On an ESP32 DevKit, ESPHome’s usual I²C pins are GPIO21 for SDA and GPIO22 for SCL.

ESP32 DevKitBME2803V3VINGNDGNDGPIO21SDAGPIO22SCLESP32 DevKitBME2803V3VINGNDGNDGPIO21SDAGPIO22SCL
Four wires: power at 3.3 V, ground, and the two I²C lines. Most BME280 boards have their own pull-up resistors, and ESPHome also turns on the ESP32’s internal ones by default.

Add this to the end of the file:

i2c:
  sda: GPIO21
  scl: GPIO22
  scan: true                   # lists the addresses it finds

sensor:
  - platform: bme280_i2c
    address: 0x76              # or 0x77, see the log
    temperature:
      name: Temperature
    pressure:
      name: Pressure
    humidity:
      name: Humidity
    update_interval: 60s
  • i2c: → the bus and its pins. scan: true, the default, lists the addresses it finds in the log.
  • platform: bme280_i2c → the BME280 driver. Its default address is 0x77; many cheap boards answer on 0x76, as here. Our BME280 address page explains how the SDO pin chooses between them.
  • Each reading gets a name, which becomes an entity in Home Assistant. update_interval: 60s reads the sensor once a minute.

Prefer to click? Our generator builds an equivalent file, with this BME280 already added, and makes the keys for you. It puts the API key in the file itself rather than in secrets.yaml, and adds Wi-Fi signal and uptime sensors.Open the ESPHome generator

Choosing a different sensor? Our sensor comparison puts the common ones side by side, from the DHT22 to the SHT4x.

First flash over USB, then over Wi-Fi

The very first install has to go over a USB cable. In the Device Builder, click Install on the device card and pick how:

  • Plug into this computer flashes from your browser. It uses Web Serial, which needs a secure page: the dashboard opened over HTTPS, or on localhost, as with the desktop app.
  • Plug into the computer running ESPHome Device Builder flashes from the machine that runs the dashboard, for example your Home Assistant server.
  • Manual download, then Factory format, gives you a .bin file to write with ESPHome Web: Connect, choose the port, Install.

On the command line, esphome run living-room.yaml asks which serial port to use. If no port appears:

  • Try another USB cable: charge-only cables have no data wires.
  • Install the driver for the board’s USB-serial chip, usually a CH34x or a CP2102.
  • Hold the board’s BOOT button while you plug it in, then release it: that starts the chip in download mode.

Once the device has joined your Wi-Fi, every later Install offers Wirelessly, and esphome run uploads over the network.

Adding it to Home Assistant

If mDNS works on your network, Home Assistant finds the new device by itself. Go to Settings → Devices & services: under Discovered you’ll see an ESPHome card with its name. Click Configure, enter the encryption key when asked (when the Device Builder runs as a Home Assistant app it is often filled in for you), and pick an area.

If nothing is discovered, click Add integration, choose ESPHome and enter living-room.local or the device’s IP address. The sensor’s three readings appear as entities, ready for the dashboard.

The integration’s options include Allow the device to perform Home Assistant actions, off by default. Turn it on only for devices you trust, and only if your YAML needs it.

Reading the logs

The log is where every problem shows up first. In the Device Builder, Logs reads it over USB if the board is plugged in, otherwise over the network; on the command line, esphome logs living-room.yaml. When you connect, the device prints its configuration, including the I²C scan:

[C][i2c:113]: Results from bus scan:
[C][i2c:119]: Found device at address 0x76

The number after i2c is a line number in ESPHome’s source code, so it changes from one version to the next. “Found no devices” means a wiring or power problem, not a YAML one. A reading every minute, in [D] lines, means the sensor works.

Common errors

SymptomLikely causeWhat to do
No serial port appearsCharge-only cable or missing driverUse a data cable; install the CH34x or CP2102 driver; hold BOOT while plugging in
Installs, then reboots in a loopWrong board in the YAML, or a strapping pin pulled the wrong way at bootCheck the board ID; move parts off GPIO0, 2, 5, 12 and 15 on the ESP32 (our ESP32 pinout marks them). After 10 failed boots ESPHome starts in safe mode, with only Wi-Fi and updates
“Found no devices”, or the sensor isn’t foundSDA and SCL swapped, wrong address, no power, or a BMP280Check the four wires; set the address the scan shows; see the tip above
ADC readings stuck or failingAn ADC2 pin, which the original ESP32 shares with Wi-FiUse an ADC1 pin: GPIO32 to 39 on the ESP32
Never joins Wi-Fi, fallback hotspot appearsA 5 GHz-only network, or a typo in secrets.yamlUse a 2.4 GHz network: in ESPHome only the ESP32-C5 can use 5 GHz, with its band_mode option
Reboots every 15 minutesThe API’s reboot_timeout: no Home Assistant connectedAdd the device to Home Assistant, or set reboot_timeout: 0s under api:

Strapping pins decide how the chip starts; a sensor or LED holding one of them high or low can stop it booting.

Security

  • API encryption. Always set a key: without it the connection is neither encrypted nor tied to a secret, so any device on your network can connect.
  • Encrypted updates. With encryption: under ota: (ESPHome 2026.9 and newer) the device only accepts firmware encrypted with your key. Older guides use password:; ESPHome now warns that it costs flash and RAM and recommends encryption, and the two can’t be combined.
  • A password on the fallback hotspot. Its page lets whoever connects change the Wi-Fi settings and upload firmware.
  • Keep secrets.yaml private, and back it up: without the key you can’t update the device over Wi-Fi.

Keeping it up to date

ESPHome ships a new version every month. Updating the Device Builder (or pip install --upgrade esphome) doesn’t change your devices: each one keeps running the firmware last installed on it until you click Install again. Read the release notes’ breaking changes first, then update one device before the rest.

On a battery: deep sleep

A sensor that only needs to report every few minutes can sleep in between with the deep_sleep: component, set with run_duration and sleep_duration. While it sleeps Home Assistant shows it as unavailable, and it can only take an update while it is awake. Choosing the board, battery and regulator, with real current figures, is covered in our guide to powering an ESP32 from a battery.

Frequently asked questions

Do I need Home Assistant to use ESPHome?

No. The Device Builder also runs as a desktop app, in Docker or from the command line, and ESPHome devices can publish over MQTT or show a local web page. The native API, though, is made for Home Assistant.

Which ESPHome version does this guide use?

ESPHome 2026.10.2, the current release on 4 November 2026. Every configuration shown passes esphome config on it.

ESP32 or ESP8266?

An ESP32 for anything new: more memory and pins, and the default for most examples. An ESP8266 such as the D1 mini still works for simple sensors and relays.

Arduino or ESP-IDF?

Since ESPHome 2026.1 the ESP32 uses ESP-IDF unless you say otherwise. Arduino is still supported with framework: type: arduino, for libraries or components that need it.

Should I use an OTA password or encryption?

Encryption, on ESPHome 2026.9 or newer: encryption: under ota: reuses the API key. ESPHome now warns about password:, and you can’t use both.

Why does my device reboot every 15 minutes?

With api: and no Home Assistant connected, the device reboots after reboot_timeout, 15 minutes by default, assuming the network is stuck. Add it to Home Assistant, or set reboot_timeout: 0s.

My BME280 gives no readings and the log says “Wrong chip ID or no response”. Why?

It is probably a BMP280, which has no humidity sensor: the BME280 driver expects chip ID 0x60, a BMP280 answers with a different one, and the driver stops. Use platform: bmp280_i2c; our BME280 vs BMP280 comparison shows how to tell them apart.

Can I flash from a phone?

Not with ESPHome Web: Web Serial isn’t available on iOS, and the ESP Web Tools documentation says Android isn’t supported yet. Use a computer for the first flash; after that, updates go over Wi-Fi.

Sources

  1. ESPHome: Install ESPHome
  2. ESPHome: Getting started
  3. ESPHome: Physically connecting to your device
  4. ESP Web Tools (ESPHome Web)
  5. ESPHome: ESP32 Arduino to ESP-IDF migration guide
  6. ESPHome 2026.9.0 release notes (encrypted updates)
  7. ESPHome on PyPI (current version)
  8. ESPHome: Native API component
  9. ESPHome: WiFi component
  10. ESPHome: Captive portal
  11. ESPHome: Safe mode
  12. ESPHome: I²C bus
  13. ESPHome: I²C scan log messages (source, 2026.10.2)
  14. ESPHome: BME280 sensor
  15. ESPHome: BME280 chip ID check (source, 2026.10.2)
  16. ESPHome: ADC sensor
  17. ESP-IDF: ADC oneshot driver (ADC2 and Wi-Fi)
  18. Home Assistant: ESPHome integration
  19. Apollo Automation: connecting an ESPHome device to Home Assistant
  20. Waveshare: your first ESPHome device (install options)