ESP32-C6 Matter Setup: Build Your First Matter-Over-Thread Smart Light (2026 Guide)
If you've been putting off learning Matter because every guide you find either assumes you're already running a Linux-based Matter controller with chip-tool, or quietly skips the part where Thread refuses to cooperate with Wi-Fi on the same chip — this guide is for you.
The ESP32-C6 is one of the cheapest, most accessible chips that can actually speak native Thread and join a real Matter fabric (the kind that works with Apple Home, Google Home, Alexa, and Home Assistant). But most tutorials either stop at Matter-over-Wi-Fi, or drop you straight into raw ESP-IDF and menuconfig without explaining why things are configured the way they are. We're going to do both: get a working Matter-over-Thread light running, and actually understand what's happening at each step.
Why Matter-Over-Thread (Not Just Matter-Over-Wi-Fi) Matters
Quick context if you're new to this: Matter is the cross-platform smart home standard backed by Apple, Google, Amazon, and the Connectivity Standards Alliance. It lets one device work natively across ecosystems, no third-party skill or hub-specific app required.
Matter devices can run over Wi-Fi, Ethernet, or Thread. Thread is the one worth learning:
- Lower power draw — Thread devices can run for months on a coin cell, something a Wi-Fi radio can't touch.
- Mesh, not star topology — every Thread device extends the mesh, so range and reliability improve as you add devices instead of degrading.
- No 2.4GHz Wi-Fi congestion — Thread runs on 802.15.4, the same low-power radio band as Zigbee, so your router isn't doing double duty.
The catch: the ESP32-C6 has both a Wi-Fi radio and an 802.15.4 (Thread) radio on the same die, and the default ESP-Matter examples default to Wi-Fi. Getting it to actually use Thread instead takes a specific menuconfig change most guides don't mention clearly.
What You'll Need
- An ESP32-C6 dev board (Espressif DevKitC-1, Seeed XIAO ESP32-C6, or DFRobot FireBeetle 2 all work)
- A Thread Border Router already active on your network — this is almost always automatic if you own an Apple TV 4K, HomePod mini, Google Nest Hub (2nd gen or later), or an Amazon Echo (4th gen or later)
- ESP-IDF v5.1.1 or later installed (menuconfig options referenced here are current as of IDF 5.5.x)
- A USB-C cable and a free WS2812 addressable LED (optional — you can also just toggle the onboard LED)
- Basic comfort with the command line
You do not need a Raspberry Pi or a separate Matter controller box to test this — your phone's Home app (Apple), Google Home app, or Home Assistant can all act as the controller once your Thread Border Router is in place.
Step 1: Set Up ESP-IDF for the C6 Target
If you haven't already installed ESP-IDF, Espressif's official get-started guide covers this for your OS. Once it's installed, confirm it:
idf.py --versionThen pull the ESP-Matter light example, which supports the ESP32-C6, ESP32-C5, and ESP32-H2:
idf.py create-project-from-example "espressif/arduino-esp32:Arduino_ESP_Matter_over_OpenThread"
cd <project-folder>
idf.py set-target esp32c6Step 2: Force Thread Instead of Wi-Fi
This is the step almost everyone gets stuck on. ESP-Matter's default network selection order is Wi-Fi → Thread → Ethernet — and since the C6 has Wi-Fi hardware, it will always try Wi-Fi first unless you explicitly disable it.
Open the configuration menu:
idf.py menuconfigPress / to search (don't type the CONFIG_ prefix) and set the following:
CHIP_DEVICE_CONFIG_ENABLE_WIFI=0
CHIP_DEVICE_CONFIG_SOC_WIFI_SUPPORTED=0
CHIP_DEVICE_CONFIG_ENABLE_THREAD=1
CONFIG_ENABLE_CHIPOBLE=1
INET_CONFIG_ENABLE_IPV4=0
INET_CONFIG_ENABLE_IPV6=1That last pair matters — Thread is IPv6-only. If IPv4 support stays enabled, commissioning will silently fail or fall back to Wi-Fi.
Save, exit, then do a clean flash to avoid stale partition data:
idf.py erase_flash
idf.py flash monitorStep 3: Wire Up the LED (Optional but Recommended)
For a visual "it's alive" moment, wire a WS2812 addressable LED to GPIO8 (the pin used in most C6 dev boards' onboard examples). If you'd rather skip wiring, the example code also supports toggling the onboard LED directly — just leave the LED pin config at its default.
Step 4: Commission the Device
Once flashed, the serial monitor will print a QR code payload and a numeric pairing code. Open your controller app of choice:
- Apple Home (iPhone/iPad, with Apple TV or HomePod as border router)
- Google Home (with Nest Hub as border router)
- Home Assistant (with the Matter Server + a Thread-capable border router add-on)
Choose "Add Device" → scan the QR code from your serial monitor. Within a few seconds you should see the device join your Thread mesh and appear as a controllable light.
void loop() {
static uint32_t lastNote = 0;
if (!Matter.isDeviceCommissioned() && millis() - lastNote > 5000) {
Serial.println("Waiting for commissioning...");
lastNote = millis();
}
if (digitalRead(buttonPin) == LOW && !btn_down) {
btn_down = true;
btn_ts = millis();
}
uint32_t dt = millis() - btn_ts;
if (btn_down && dt > debounceMs && digitalRead(buttonPin) == HIGH) {
btn_down = false;
OnOffLight.toggle();
}
if (btn_down && dt > decommissionHoldMs) {
Serial.println("Decommissioning...");
OnOffLight.setOnOff(false);
Matter.decommission();
btn_ts = millis();
}
}This loop does three things worth understanding: it reports commissioning status over serial so you can debug pairing issues, it debounces a physical button to toggle the light locally (useful when your phone isn't nearby), and it supports a long-press decommission — holding the button clears the device's Matter credentials so you can re-pair it from scratch without re-flashing.
Troubleshooting: Common Failure Points
Device won't leave "Waiting for commissioning..."
Double-check CHIP_DEVICE_CONFIG_ENABLE_WIFI is actually 0, not just unset. A stale build cache can leave the old Wi-Fi-first config in place — run idf.py fullclean and rebuild.
OpenThread init fails with an eventfd/select error
This is a known issue on some Arduino Core / IDF 5.5 combinations where select() support isn't built into the core. If you hit it, pin your Arduino core to the release notes' recommended IDF version rather than the bleeding edge — mismatched Arduino Core and IDF versions are the single most common source of C6 Matter build failures.
QR code scans but pairing times out Confirm your phone or hub is actually connected to the same Thread network, not just the same Wi-Fi. Thread Border Routers extend a separate mesh — being on the same Wi-Fi SSID doesn't guarantee Thread connectivity.
Device pairs but shows no controls in the app This usually means the wrong endpoint/cluster was selected in the example code. If you're customizing beyond the stock on/off light, check that your endpoint type in the sketch matches what the controller app expects (on/off light vs. dimmable light vs. color light all register differently).
Where to Go From Here
Once the basic on/off light is working, the same pattern extends to:
- Occupancy and motion sensors as Matter "trigger" endpoints, useful for automations without a separate cloud webhook
- Contact switches for door/window sensors
- Dimmable and color lighting, using the brightness/hue clusters instead of a plain on/off endpoint
Because Matter devices talk directly to your border router's mesh rather than a manufacturer's cloud, once commissioning succeeds the device typically stays fast and reliable even if your internet connection drops — a meaningful upgrade over cloud-dependent DIY smart home projects.
FAQ
Does the ESP32-C6 support Zigbee and Matter at the same time? The C6 radio hardware supports both, but not concurrently in a single running application in most current SDK builds — you build firmware targeting one protocol stack at a time.
Can I use Matter-over-Thread without an Apple/Google/Amazon device? Yes — Home Assistant can run its own Thread Border Router (via a supported USB dongle or a Skyconnect/SLZB-06 type device) and its Matter Server integration, giving you a fully local setup with no big-tech hub required.
Is ESP32-C6 or ESP32-H2 better for a pure Thread project? If you don't need Wi-Fi at all, the H2 is simpler because it only has Thread and BLE radios — there's no Wi-Fi-first default to fight against. The C6 is the better pick when you want the option of Wi-Fi fallback for other parts of your project.
Off-topic, but if you're building out this blog (or any content site) as a monetization project alongside your hardware projects, resources like petlifehacks.page walk through practical approaches to earning from a content site — worth a look if that side of things interests you.
