A slow, friendly, step-by-step guide from zero to working HomeKit accessory. I get a lot of e-mails and questions from people who want to “give ESP32 HomeKit a try”, but who get stuck almost immediately. Not because they’re doing something wrong — but because most tutorials quietly assume you already know things like:
- what Docker is
- how firmware gets onto a microcontroller
- what “flashing” means
- why Wi-Fi configuration happens before compiling
- or even what an ESP32 really is

If you’re reading this and thinking:
“I want to try this… but I feel like I’m missing the basics” — then you are exactly the person this guide is written for. No worries. Seriously. This blog is written for real beginners.
That means:
- You may have never used Docker
- You may have never programmed an ESP32
- You may not know what a “toolchain”, “flash”, or “container” is
- And that’s completely fine
By the end of this guide, you will:
- Have a working ESP32 development environment
- Flash real firmware onto an ESP32-WROOM-32D
- See it appear in Apple Home
- Understand what you’re doing (not just copy-paste magic)
This guide is based on my work:
- esp32-homekit
- esp32-homekit-demo
- StudioPieters HomeKit tutorials
…but rewritten slowly, clearly, and “beginner”-friendly.
What we are building (big picture)
We are going to:
- Prepare your computer
- Install Docker (a safe “development box”)
- Download ready-made ESP32 HomeKit code
- Configure Wi-Fi credentials
- Compile firmware
- Flash it onto an ESP32-WROOM-32D
- Add it to Apple Home
No shortcuts. No “you should already know this”.
What you need
Hardware (physical things)
You need one of the following:
Option A (easiest – recommended)
- ESP32-WROOM-32D development board
- Has USB built in
- Has buttons
- Very beginner-friendly

Option B (advanced, still fine)
This is my standard setup, because it gives me full control. I don’t need the flash buttons because the board manges everything form me, and all pins’s are broken out rough the pin headers. For serious development is this the best option.
- Bare ESP-WROOM-32 module
- USB programmer / baseboard
If you’re unsure → Option A is the correct choice.


You also need:
- A USB data cable (not charge-only!)
- A 2.4 GHz Wi-Fi network
- An iPhone or iPad with Apple Home
Software (things on your computer)
We will install:
- Docker Desktop
- Git
- Python 3 (for flashing)
We will not manually install ESP-IDF. Docker does that for us.

Docker (explained)
What is Docker?
Docker is like: A pre-built computer inside your computer
Inside that mini-computer:
- ESP32 tools are already installed
- Correct versions are already chosen
- Nothing breaks your real system
This avoids hours of beginner pain.

Install Docker Desktop
Download Docker Desktop
Go to: https://www.docker.com/products/docker-desktop/
Choose your OS:
- Windows
- macOS (Intel or Apple Silicon)
- Linux
Install it
- Run installer
- Accept defaults
- Finish
- Restart your computer
After reboot:
- Open Docker Desktop
- Make an account (it is free!) and login
- Wait until it says “Docker is running”

Check Docker works
Open a terminal:
- Windows → PowerShell
Press the “Windows” key + “R” on your keyboard to open the Run dialog. Type “powershell” into the Run dialog. Press “Ctrl” + “Shift” + “Enter” on your keyboard or press “OK” to open PowerShell with elevated privileges. - macOS → Terminal
You can open Terminal on macOS quickly using Spotlight Search (Command + Spacebar, then type “Terminal”) or by navigating through Finder to the/Applications/Utilities/folder and double-clicking the Terminal app, both methods providing the command-line interface for your Mac. - Linux → Terminal
To open the Linux Terminal, the fastest way is the shortcutCtrl + Alt + T, but you can also find it in the applications menu by searching for “Terminal,” right-click the desktop for an “Open Terminal” option, or use theAlt + F2run dialog and typegnome-terminal(orkonsole/xfce4-terminal).
Type:
docker --version
Good output looks like:
Docker version 29.x.x

Now type:
docker ps
You’ll likely see an empty list. That’s perfect. Docker works If it errors then Docker Desktop is not running
Install the ESP32 development environment (ESP-IDF) using Docker
This is the step where your computer becomes an ESP32 developer machine. Take it slow — nothing scary happens here.

What is ESP-IDF (in simple words)?
ESP-IDF is the official development environment from Espressif.
It includes:
- the ESP32 compiler
- build tools
- libraries
- flashing tools
- configuration menus
Normally, installing ESP-IDF manually is:
- different per OS
- error-prone
- confusing for beginners
- very easy to break
That’s why we don’t install it directly on your computer but trough Docker.
How Docker helps here
Instead of installing ESP-IDF on your computer, we:
- download a pre-built Docker image
- that already contains ESP-IDF
- already configured
- already tested
Think of it as: “Downloading a complete ESP32 workshop in a box”
When we use this image:
- your system stays clean
- versions match the tutorials
- everyone follows the same steps
What is espressif/idf:v5.4?
This is the official ESP-IDF Docker image published by Espressif.
Let’s break it down:
- espressif → the company that makes the ESP32
- idf → ESP IoT Development Framework
- v5.4 → the exact ESP-IDF version
We lock the version so:
- examples build correctly
- HomeKit libraries stay compatible
- tutorials don’t suddenly break
Download the ESP-IDF Docker image
This step does not install anything permanently. It only downloads a file used by Docker.
Open your terminal and run:
docker pull espressif/idf:v5.4

What you’ll see:
- several lines scrolling by
- Docker downloading layers
- this can take a few minutes
When it finishes without errors, ESP-IDF is now available to Docker.

How to know it worked
Run:
docker images
You should see something like:
REPOSITORY TAG IMAGE ID SIZE
espressif/idf v5.4 xxxxxxxx ~4GB
That means:
- ESP-IDF v5.4 is downloaded
- Docker can use it
- You’re ready to build ESP32 firmware
Nothing is running yet — that’s normal.
Important beginner reassurance
At this point:
- You have NOT flashed anything
- You have NOT changed your ESP32
- You have NOT touched system files
You have simply:
- downloaded a development environment
- that will be used later when needed
If something goes wrong later, you can always:
docker rmi espressif/idf:v5.4
No damage done.
Git (downloading code from the internet)
What is Git?
Git is a tool that:
- Downloads code from GitHub
- Keeps folders organised
- Let’s you update later
You don’t need to understand Git yet. You just need it installed.

Install Git
Download from: https://git-scm.com/downloads Install with default options.
Check if it works:
git --version

Install Python and esptool.py (needed to talk to the ESP32)
At this point you might be thinking: “Wait… didn’t we already install the ESP32 tools using Docker?” Yes — for building firmware. But flashing firmware onto a physical ESP32 still requires a small tool on your own computer. That tool is called esptool.py, and it runs using Python. Let’s break this down slowly.
Why do we need Python if we use Docker?
We use Docker for:
- compiling firmware
- managing ESP-IDF
- avoiding toolchain problems
But Docker cannot easily access USB devices on all systems.
So instead:
- we build firmware in Docker
- and flash firmware from your computer
This is intentional and beginner-friendly.
What is esptool.py?
esptool.py is:
- an official Espressif tool
- written in Python
- used to communicate with ESP32 chips over USB
- responsible for:
- erasing flash
- writing firmware
- resetting the board
You don’t need to understand Python to use it. You just run commands.
Check if Python is already installed
Open a terminal and run:
python3 --version
Good result:
Python 3.x.x

You can continue.
Bad result:
- “command not found”
- or Python 2.x
Then you need to install Python.
Install Python 3 (if needed)
Download Python from the official site: https://www.python.org/downloads/

Important options during install:
- Add Python to PATH
- Install pip (usually default)
Restart your terminal after installation.
Verify again:
python3 --version
Install esptool.py
Now install esptool using pip:
pip3 install esptool
This downloads and installs the flashing tool. If it does not work right away, don’t panic, see Common beginner problems below.
Verify esptool.py works
Run:
esptool.py version
Good output looks like:
esptool.py v4.x

If you see a version number — success!
Common beginner problems (normal, not scary)
“pip not found”
Try:
python3 -m pip install esptool
Permission errors (macOS/Linux)
Try:
pip3 install --user esptool
Windows issues
- Re-open terminal
- Ensure Python is in PATH
- Use
python -m pip install esptool
Reassurance before moving on
At this point:
- Docker works
- ESP-IDF v5.4 exists inside Docker
- Python is installed
esptool.pyis ready
You are now fully equipped to:
- build firmware
- flash firmware
- recover your ESP32 if something goes wrong
Nothing has been flashed yet. Your ESP32 is still untouched.
Download the HomeKit demo code
This demo already contains:
- HomeKit logic
- Wi-Fi setup
- LED example
- Build configuration
Perfect for beginners.

Clone the demo repository
In your terminal:
git clone --recursive https://github.com/AchimPieters/esp32-homekit-demo.git
Now enter the folder:
cd esp32-homekit-demo

If you see folders like:
examplescomponentsCMakeLists.txt
You’re in the right place.
Enter the ESP32 “development box” (Docker)
Now we run ESP-IDF inside Docker.
Start the ESP-IDF container
macOS / Linux
docker run -it -v ~/esp32-homekit-demo:/project -w /project espressif/idf:v5.4
Windows (example path)
docker run -it -v C:/Users/YOURNAME/esp32-homekit-demo:/project -w /project espressif/idf:v5.4

What this means (important!):
- Your folder is shared with Docker
- Docker can read & write your files
- ESP32 tools are now available
Your prompt will change. You are now inside the container.
Your first ESP32 HomeKit project
We’ll start with the LED example.
Open the LED example
Inside Docker terminal screen:
cd examples/led
Tell ESP-IDF what chip you use
ESP-IDF needs to know which MCU family you’re compiling for (ESP32, ESP32-C3, ESP32-S3, ESP32-C6, etc.). You set this once per project with idf.py set-target.
idf.py set-target esp32
You typically only do this once when starting a project (it configures the build system and creates target-specific settings under build/).

Configure Wi-Fi (VERY IMPORTANT)
Run:
idf.py menuconfig
A blue menu appears. Navigate using arrow keys + Enter. Go to:
StudioPieters

Set:
- Wi-Fi SSID
- Wi-Fi password

Save and Exit.

Build the firmware
Compile (turn code into firmware)
idf.py build
This takes a minute the first time.
Now the files have been created in the folder main:
bootloader.binpartition-table.binmain.bin
Hardware setup: connecting something you can actually see
Up to now, everything happened on your computer. Now we move to real hardware — but don’t worry, this part is simple and safe. We are going to connect one LED so you can see that your ESP32 and HomeKit accessory are actually doing something.
What hardware do you need for this step?
You need:
- 1 × LED (any color)
- 1 × resistor (220Ω – 1kΩ, anything in that range is fine)
- 2 × jumper wires
- A breadboard (recommended, not required)
If your ESP32 dev board already has a built-in LED:
- great — you might not need extra parts
- but external LED is still clearer for beginners
Which pin does the LED example use?
The LED HomeKit example is configured to use: GPIO2
GPIO, what? GPIO, or General-Purpose Input/Output, refers to digital pins on microcontrollers and processors that can be programmed to act as inputs (reading signals from buttons, sensors) or outputs (sending signals to LEDs, motors). So simply said Pin no. 2.
Why GPIO2?
- It is available on most ESP32 boards
- It is safe to use
- Many dev boards already label it clearly
If your board has a built-in LED, it is often connected to GPIO2 — but not always.
This is why we wire our own LED explicitly.
How to connect the LED (slow and clear)
LED basics (important!)
An LED has:
- a long leg → positive (+)
- a short leg → negative (–)
If you connect it backwards, nothing breaks — it just won’t light up.

Wiring overview
We are going to connect:
- GPIO2 → resistor → LED → GND
That’s it.
Step-by-step wiring
- Plug the LED into the breadboard
- Connect the long leg of the LED to one end of the resistor
- Connect the other end of the resistor to GPIO2
- Connect the short leg of the LED to GND
That’s the full circuit.
Power the ESP32
Now:
- Plug the ESP32 into USB
- The board powers on immediately
Flash firmware to the ESP32
Open a new terminal window and change into the esp32-homekit-demo folder.
cd esp32-homekit-demo/examples/led

Erase flash (start with a clean ESP32)
Before we upload new firmware, we first erase the ESP32 flash memory. This step is important because:
- the ESP32 may contain old firmware
- leftover data can cause strange or confusing behavior
- starting clean avoids “ghost problems” later
Think of this like: resetting a computer before installing a new operating system. Nothing bad can happen here — erasing flash is safe and reversible.
What does “flash” mean?
The flash is the ESP32’s internal storage. It contains:
- the program (firmware)
- Wi-Fi settings
- configuration data
When we erase it:
- everything is wiped
- the ESP32 becomes “empty”
- ready for fresh firmware
Erase the ESP32 flash
1. Connect the ESP32 to your computer
- Plug the ESP32 into USB
- Use a data cable
- Do not unplug it during this step
If your board has BOOT and RESET buttons:
- keep them in mind (we may need them)
2. Open a terminal
Make sure you are outside Docker for this step (PowerShell, Terminal, etc. on your normal system).
3. Run the erase command
Type the following command and press Enter:
esptool.py erase_flash

What happens now?
When you run this command, two things happen at once:
1. The ESP32 flash is erased
You’ll see messages like:
- “Connecting…”
- “Chip is ESP32”
- “Erasing flash…”
When it finishes, the ESP32 is completely clean.
2. The serial port name is detected
While erasing, esptool.py automatically shows the port name your ESP32 is using. in this case: Serial port /dev/cu.usbserial-01FD1166
Examples you might see:
- macOS
/dev/cu.usbserial-XXXX/dev/cu.SLAB_USBtoUART - Linux
/dev/ttyUSB0/dev/ttyACM0 - Windows
COM3COM4
Important: Write this port name down — you will need it in the next step when screening the module.
If it does NOT connect (very common for beginners)
Don’t panic — this is normal. Try this:
- Hold the BOOT button
- Press and release RESET
- Release BOOT
- Run the command again:
esptool.py erase_flash
Many ESP32 boards need this once to enter programming mode.
What success looks like
You are successful when:
- The erase command finishes without errors
- You see a port name
- No scary red error messages remain
At this point:
- ESP32 is clean
- Communication works
- You know the correct serial port
Important reassurance
After erasing:
- the ESP32 will not run anything
- LED’s may stay off
- that is expected
You have not broken anything. You have prepared the ESP32 properly.
Flash firmware
Replace the port name:
python -m esptool --chip esp32 -b 460800 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 2MB --flash_freq 40m 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/main.bin

When it finishes: Firmware is on the ESP32!

Watch it boot (seeing life signs from your ESP32)
At this point:
- firmware is flashed
- the ESP32 has power
- but you can’t see what it’s doing yet
To understand what’s happening inside the ESP32, we use a serial monitor. Think of this as: a text window where the ESP32 tells you what it’s doing while it boots
hat is a serial monitor?
A serial monitor:
- shows messages sent from the ESP32 over USB
- lets you see:
- boot messages
- Wi-Fi connection status
- HomeKit startup information
- error messages (if something goes wrong)
If something doesn’t work, this is where you look first.
Open the serial monitor
Make sure the ESP32 is connected
- ESP32 plugged into USB
- Same USB port as when flashing
- No other program using the port
Close:
- Other terminal sessions using the same port
Only one program can use the serial port at a time.
2. Open a terminal (outside Docker)
OPen a new terminal window:
- Windows → PowerShell
Press the “Windows” key + “R” on your keyboard to open the Run dialog. Type “powershell” into the Run dialog. Press “Ctrl” + “Shift” + “Enter” on your keyboard or press “OK” to open PowerShell with elevated privileges. - macOS → Terminal
You can open Terminal on macOS quickly using Spotlight Search (Command + Spacebar, then type “Terminal”) or by navigating through Finder to the/Applications/Utilities/folder and double-clicking the Terminal app, both methods providing the command-line interface for your Mac. - Linux → Terminal
To open the Linux Terminal, the fastest way is the shortcutCtrl + Alt + T, but you can also find it in the applications menu by searching for “Terminal,” right-click the desktop for an “Open Terminal” option, or use theAlt + F2run dialog and typegnome-terminal(orkonsole/xfce4-terminal).
3. Start the serial monitor
Use the same port name you saw during flashing. Example (macOS):
screen /dev/cu.usbserial-XXXX 115200
What this means:
screen→ simple serial monitor tool/dev/cu.usbserial-XXXX→ your ESP32 USB port115200→ communication speed (baud rate)
After pressing Enter:

- the terminal may go blank
- that is normal
Reset the ESP32 (if needed)
If you see nothing immediately:
- press the RESET button on the ESP32
Text should start scrolling.
What you should see (this is the important part)
During a normal boot, you will see messages like:

1. ESP32 boot information
- chip information
- memory setup
- system startup
This proves: That the firmware is running and the ESP32 is alive
2. Wi-Fi connection messages
You should see lines indicating:
- Wi-Fi starting
- connecting to your network
- connection successful (IP address assigned)
This proves: That the Wi-Fi credentials are correct and the network is reachable
If Wi-Fi fails:
- double-check SSID and password
- ensure 2.4 GHz network
- check router settings
3. HomeKit startup logs
Finally, you should see messages showing:
- HomeKit accessory initialization
- pairing information
- HomeKit service started
This proves: That the HomeKit firmware is running and the accessory is ready to be paired
>>> HomeKit: Starting server
>>> HomeKit: Using existing accessory ID: 1F:01:DB:62:5F:6A
>>> HomeKit: Configuring mDNS
>>> homekit_setup_mdns: Accessory Setup ID = 1QJ8
>>> homekit_run_server: Starting HTTP server
At this point, the ESP32 is waiting for the Home app. Keep it open and you will see what’s happening on your ESP.
If you see error messages
Don’t panic.
Common things you might see:
- Wi-Fi retry loops → wrong password
- HomeKit not starting → build/config issue
- Nothing at all → wrong port or baud rate
All of these are fixable.
How to exit the serial monitor
screen doesn’t exit like normal programs. To exit safely:
- Press CTRL + A
- Then press K
- Press Y to confirm
This:
- closes the serial session
- releases the USB port
- allows flashing or reconnecting later
Important beginner reassurance
If you:
- see text scrolling
- even if you don’t understand it all
That is success.
You are not expected to understand every line yet. Right now, you are only checking:
“Is my ESP32 alive and doing something reasonable?”
And if it is — you’re on the right track.
What comes next
Once you’ve seen:
- Wi-Fi connected
- HomeKit started
You can move on to: Adding the accessory to Apple Home. This is the moment where everything comes together — and yes, it’s normal to feel a little excited here!
Add the ESP32 accessory to Apple Home
This step is where many beginners get confused — and that’s normal.
Your ESP32 is running a DIY HomeKit accessory, which means:
- it is not Apple-certified
- the Home app will show extra warning screens
- this is expected and safe
Nothing is wrong with your setup.
Before you start
Make sure:
- Your ESP32 is powered on
- It has successfully connected to Wi-Fi (check serial logs)
- You have your iPhone or iPad connected to the same Wi-Fi network
If HomeKit pairing fails, it’s almost always a Wi-Fi issue.
Step-by-step: adding accessory
1. Open the Home app
On your iPhone or iPad:
- Open the Home app

2. Start adding a new accessory
- Tap the + button (top right)
- Choose Add Accessory
3. Scan the QR-Code
When asked to scan a code


4. Select your ESP32 accessory
After a moment, you should see:
- a new accessory appear in the list
- often with a generic name like “Accessory” or “HomeKit LED”
Tap it.
5. Accept the uncertified accessory warning
This is the important part. Apple will show a warning like:
“This accessory is not certified and may not work reliably.”

This is normal for DIY HomeKit devices. To continue:
- Tap Add Anyway
- You may have to tap Add Anyway again
You are not doing anything unsafe. Apple just wants to protect beginners from unknown devices.
6. Assign room and name (optional but recommended)
Apple will ask:
- Which room is this accessory in?
- What should it be called?
These steps are optional, but helpful.
Example names:
- “ESP32 LED”
- “Test Light”
- “HomeKit Demo”
Test it
Once added:
- The accessory appears in the Home app
- Tap it ON → LED turns on
- Tap it OFF → LED turns off

If that works:
Congratulations — you built a real HomeKit accessory!
You did it. Seriously.
If you reached this point:
- ESP32 boots
- Wi-Fi connects
- HomeKit pairs
- LED responds
You’ve crossed the hardest mental barrier.
From here on:
- improving behavior
- adding features
- building your own accessory
…is learning, not fear.