Zigbee2MQTT vs ZHA: Home Assistant Zigbee Integrations Compared

Two ways to talk Zigbee, one decision you'll live with for years

If you’re building a smart home on Home Assistant and you’ve sensibly decided to avoid the cloud, you’ll standardise on Zigbee for your sensors and switches. Then you hit the fork in the road: do you talk to your Zigbee radio through ZHA (the built-in integration) or Zigbee2MQTT (an external bridge)? People treat this like a religious war. It isn’t. Both are good. But the choice shapes your setup for years, because migrating a meshed Zigbee network of fifty devices to a different coordinator software is a tedious evening you’ll only want to do once.

Advertisement

Both need a Zigbee coordinator — a USB stick or Ethernet adapter, commonly a Texas Instruments CC2652 or a Silicon Labs EFR32-based device. The difference is what sits on top.

ZHA is a Home Assistant integration. It runs inside HA, talks directly to the coordinator, and exposes devices as native HA entities. No extra services, no message broker, nothing else to maintain. It’s the path of least resistance.

Zigbee2MQTT is a separate application. It owns the coordinator, decodes Zigbee messages, and publishes them to an MQTT broker. Home Assistant then subscribes via MQTT discovery. So your stack is: stick → Zigbee2MQTT → Mosquitto → Home Assistant. More moving parts, but each part is independently inspectable, and the bridge isn’t tied to HA’s lifecycle.

The single biggest practical difference is device compatibility. Zigbee2MQTT maintains an enormous, community-curated database of device definitions — thousands of devices, with quirky vendors handled explicitly. When a new sensor model appears, support typically lands in Zigbee2MQTT first. ZHA has closed much of the gap with its “quirks” system and broad generic support, but I still occasionally meet a cheap off-brand sensor that pairs in ZHA and exposes nothing useful, then works perfectly under Zigbee2MQTT.

If you buy mainstream kit (IKEA, Aqara, Philips Hue bulbs, Sonoff), both handle it fine. If you’re the sort who buys obscure AliExpress sensors because they’re three quid, Zigbee2MQTT’s database will save you grief.

If you go the Z2M route and you’re not using the HA add-on, a compose file is the clean way:

services:
  zigbee2mqtt:
    image: koenkk/zigbee2mqtt:latest
    restart: unless-stopped
    volumes:
      - ./z2m-data:/app/data
      - /run/udev:/run/udev:ro
    devices:
      - /dev/serial/by-id/usb-Texas_Instruments_slaesh_s_CC2652RB_stick-if00-port0:/dev/ttyACM0
    environment:
      - TZ=Europe/London
    ports:
      - "8080:8080"   # web frontend

Note the by-id device path — using /dev/ttyACM0 directly is asking for pain the next time the kernel renumbers your USB devices. The minimal configuration.yaml ties it to your broker:

mqtt:
  base_topic: zigbee2mqtt
  server: mqtt://192.168.1.10:1883
  user: z2m
  password: '!secret mqtt_password'
serial:
  port: /dev/ttyACM0
frontend:
  port: 8080
advanced:
  network_key: GENERATE

That frontend is genuinely useful: a web UI showing your mesh map, signal quality, and per-device settings. ZHA’s visualisation is more basic.

ZHA’s advantage is simplicity and resilience. There’s no broker to keep alive, no second container to update, and one fewer thing to break at 2am. Pairing is done entirely in the HA UI. For a network of mainstream devices, ZHA is genuinely lower-maintenance, and the “everything in one place” story is appealing if you don’t already run MQTT for other reasons.

The flip side: ZHA is coupled to Home Assistant. Restart HA and your Zigbee network restarts with it. With Zigbee2MQTT, the bridge keeps running while you restart, upgrade, or even temporarily break HA — your automations-via-MQTT and the mesh itself stay up.

A few things that actually decide it:

  • Already run MQTT? If you’ve got Mosquitto for ESPHome or Tasmota devices, the marginal cost of Zigbee2MQTT is near zero, and you get the better device database. Lean Z2M.
  • Want the absolute minimum to maintain? ZHA. One integration, no extras.
  • Lots of cheap or exotic devices? Z2M, for the device database.
  • Want decoupling from HA’s uptime? Z2M, because the bridge survives HA restarts.
  • Want the simplest possible backup story? ZHA’s state lives in HA’s backups; Z2M is one extra z2m-data directory to capture, which is trivial but is a thing to remember.

I run Zigbee2MQTT, and if you already have a broker I’d nudge you the same way — chiefly for the device database and the operational decoupling from Home Assistant. But I won’t pretend ZHA is the wrong answer. For a tidy network of mainstream devices, ZHA’s “nothing extra to run” simplicity is a real, lasting benefit, and the device gap is much smaller than the forum wars suggest. Pick based on whether you value the broader compatibility and decoupling (Z2M) or minimal moving parts (ZHA). Whichever you choose, write down your network key and back up the coordinator config — that’s the part you’ll regret skipping, regardless of integration.

Advertisement

Related Content

Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.