Do you need a hub to run smart bulbs in Home Assistant, or does any bulb with an app do the job? It depends on the radio inside the bulb. That decides whether Home Assistant talks to the bulb directly or through a cloud that can go away. The best smart bulbs for Home Assistant fall into three camps: Zigbee bulbs on a coordinator you own, Matter over Thread bulbs behind a border router, and Wi-Fi bulbs that answer on your LAN.
We picked seven bulbs across those protocols and checked each one against the code Home Assistant and Zigbee2MQTT run, not the box art. That covers the iot_class of each integration, the ports each library opens, and the power-on settings of each Zigbee bulb. No bulb went into a lamp for this guide, so brightness figures come from maker spec pages. We pulled the integration data from Home Assistant 2026.10.4 on an Ubuntu 26.04 box in October 2026, and the Amazon listings were checked for stock that same week.
Quick picks by protocol
Start from the radio you already have in the house, then pick the bulb. Each of these stays local in Home Assistant and wins for a different reason:
- Best overall, Zigbee: Philips Hue Essential A19, works with or without a Hue Bridge, about $20 to $30 each
- Best value Zigbee four-pack: ThirdReality ZL1, about $28 to $32 for four
- Best Matter over Thread: Aqara LED Bulb T2 E26, Thread or Zigbee in one bulb, about $20 to $25
- Best Wi-Fi bulb with no hub: WiZ A19 Full Color three-pack, about $22 to $27
- Brightest Wi-Fi A19: LIFX Color A19 at 1100 lumens, about $20 to $30
- Budget Wi-Fi colour two-pack: Govee H6008 with LAN control, about $17 to $20
- Best for tinkerers: KAUF A21 with ESPHome preinstalled, about $14 to $20
Prices move every week, so treat each figure as a band and check the live price before you order. If you are starting from nothing, the Zigbee picks need a coordinator first, and our Zigbee coordinator guide covers which stick to buy. The Wi-Fi picks need nothing but your router, which is why they are the easy first bulb for a new Home Assistant install.
How we checked local control
Every Home Assistant integration ships a manifest.json that declares an iot_class. A value of local_push or local_polling means Home Assistant talks to the device on your network, and cloud_push means it goes through vendor servers. That one field is a better test of local control than any marketing claim, so we read it for every integration a bulb could land in. We installed the homeassistant package (without its dependencies, since only the manifests are read) into a Python 3.14 venv with uv and looped over the components:
uv venv -q -p 3.14 venv
uv pip install -q -p venv/bin/python --no-deps homeassistant
venv/bin/python -c "import importlib.metadata as m; print('homeassistant', m.version('homeassistant'))"
C=venv/lib/python3.14/site-packages/homeassistant/components
for x in hue wiz lifx govee_light_local tplink nanoleaf yeelight matter thread otbr zha mqtt esphome wled tuya govee_ble switchbot; do
venv/bin/python -c "import json;m=json.load(open('$C/$x/manifest.json'));print(f\"{'$x':18} {m.get('iot_class',''):14} {', '.join(m.get('requirements',[]))}\")" 2>/dev/null || echo "$x MISSING"
done
Look at the second column. Every integration a pick in this guide uses is local, and the client library version on the right is the code we read for ports in the last section:
homeassistant 2026.10.4
hue local_push aiohue==4.9.0
wiz local_push pywizlight==0.6.3
lifx local_polling lifx-async==7.6.5
govee_light_local local_push govee-local-api==3.1.0
tplink local_polling python-kasa[speedups]==0.11.0.1
nanoleaf local_push aionanoleaf2==1.0.5
yeelight local_push yeelight==0.7.16, async-upnp-client==0.48.2
matter local_push matter-python-client==1.4.0, matter-ble-proxy==0.7.1
thread local_polling python-otbr-api==3.0.0, pyroute2==0.9.6
otbr local_polling python-otbr-api==3.0.0
zha local_polling zha==2.3.1, zha-quirks==2.3.0
mqtt local_push paho-mqtt==2.1.0
esphome local_push aioesphomeapi==46.6.0, esphome-dashboard-api==1.4.0, bleak-esphome==4.0.0
wled local_push wled==1.1.1
tuya cloud_push tuya-device-handlers==0.0.31, tuya-device-sharing-sdk==0.2.15
govee_ble local_push govee-ble==1.4.0
switchbot local_push PySwitchbot==2.9.0
Two rows deserve a second look. The tuya integration is cloud_push, so the cheap Tuya and Smart Life bulbs that fill Amazon search results depend on the Tuya servers, and none of them made our list. LIFX is local_polling, which means Home Assistant asks each bulb for its state on a timer instead of the bulb announcing a change. Home Assistant 2026.10.4 polls LIFX every 10 seconds, so a colour changed from the LIFX app can take that long to show on your dashboard. ZHA also reads as polling, but that is one label for the whole integration, so it tells you nothing about how a given Zigbee bulb reports.
The label can also mislead the other way. Govee lights local declares local_push, but its coordinator asks every Govee bulb for its status on a 30-second timer, which we show in the ports section. So treat iot_class as proof that traffic stays on your LAN, and read the integration code before you trust it for how fast state changes reach you.
For the Zigbee bulbs we went one level deeper. We loaded the Zigbee2MQTT device definitions from zigbee-herdsman-converters 26.125.0 and printed what each bulb exposes, because power-on behaviour after a power cut is where cheap Zigbee bulbs usually let people down:
zigbee-herdsman-converters 26.125.0
046677592530 | Philips | Hue Essential White and Color Ambiance A19
power_on_behavior: off|on|toggle|previous
ota: yes
exposes: state, brightness, color_temp, color_temp_startup, x, y, hue, saturation, power_on_behavior, effect, effect_speed, effect_color, identify
3RCB01057Z | Third Reality | Smart Color Bulb ZL1
power_on_behavior: off|on|toggle|previous
ota: yes
exposes: state, brightness, color_temp, color_temp_startup, x, y, hue, saturation, effect, power_on_behavior, start_bind
T2_E27 | Aqara | E27 RGB led bulb
power_on_behavior: off|on|reverse|restore
ota: yes
exposes: state, brightness, color_temp, x, y, power_outage_count, device_temperature, power_on_behavior, identify, dimming_range_minimum, dimming_range_maximum, off_on_duration, on_off_duration, transition_curve_curvature, transition_initial_brightness, effect, effect_speed, effect_colors
All three Zigbee picks let you choose what happens when power returns, and all three definitions support firmware updates over Zigbee (ota: yes). Whether an update is offered still depends on a firmware image being published to the Zigbee2MQTT OTA index, and a T2 running in Thread mode is updated through Matter or the Aqara app instead. The Aqara entry is listed as T2_E27 because Zigbee2MQTT files the E26 bulb (model ID lumi.light.agl001) as a white label of the same definition. Its power_outage_count and dimming range settings are extras the other two do not have.
Smart bulbs for Home Assistant compared
We kept the table to what changes the buying decision: the radio, how Home Assistant reaches the bulb, what else you need, and how bright it gets.
| Bulb | Protocol | Home Assistant path | Needs | Lumens | White range | Price band |
|---|---|---|---|---|---|---|
| Philips Hue Essential A19 | Zigbee, Bluetooth | ZHA, Zigbee2MQTT or Hue Bridge (local push) | Zigbee coordinator or Hue Bridge | 800 | 2200 to 6500 K | $20 to $30 each |
| ThirdReality ZL1 (4-pack) | Zigbee 3.0 | ZHA or Zigbee2MQTT | Zigbee coordinator | 800 | 2700 to 6500 K | $28 to $32 per 4 |
| Aqara LED Bulb T2 E26 | Thread (Matter) or Zigbee | Matter, or Zigbee2MQTT in Zigbee mode | Thread border router or Zigbee coordinator | up to 1100 | 2000 to 9000 K | $20 to $25 |
| WiZ A19 Full Color (3-pack) | Wi-Fi, Bluetooth | WiZ integration (local push) | 2.4 GHz Wi-Fi | 800 | 2200 to 6500 K | $22 to $27 per 3 |
| LIFX Color A19 | Wi-Fi | LIFX integration (local polling) | 2.4 GHz Wi-Fi | 1100 | 1500 to 9000 K | $20 to $30 |
| Govee H6008 (2-pack) | Wi-Fi, Bluetooth | Govee lights local (local push) | LAN control enabled in the Govee app | 800 | not published | $17 to $20 per 2 |
| KAUF A21 | Wi-Fi, ESPHome | ESPHome (local push) | 2.4 GHz Wi-Fi | not published | not published | $14 to $20 |
Read the Needs column before the price. The ThirdReality four-pack is the cheapest light per bulb here, but only if a Zigbee coordinator is already plugged into your Home Assistant box. Without one, a WiZ three-pack costs less than the coordinator alone. KAUF and Govee do not publish a colour temperature range for these bulbs, so we left those cells blank rather than guess.
1. Philips Hue Essential A19 (Zigbee)
Hue Essential is the cheaper Hue line, and for Home Assistant it gives you the same radio and the same integration path as the older Hue bulbs at about half their price. The older bulbs dim lower and reach a wider white range, which matters less than the price for most rooms.
The bulb is a White and Color Ambiance A19 rated at 800 lumens and 8.8 W, with whites from 2200 to 6500 K. It carries Zigbee and Bluetooth, and you can bring it into Home Assistant two ways:
- Paired straight to your coordinator through ZHA or Zigbee2MQTT
- On a Hue Bridge, added with the
hueintegration (local_push)
We would pair it straight to the coordinator if you already run Zigbee2MQTT. Zigbee2MQTT lists the one-pack model 046677592530 with power_on_behavior and a separate color_temp_startup, so you can make it come back at a warm white after a power cut. The bridge path suits you if the bulbs are already on a Hue Bridge and the family uses the Hue app.
Who should buy it: anyone with a Zigbee network who wants a bulb that every Zigbee stack knows well, or anyone who already owns a Hue Bridge. A mains-powered Zigbee bulb also acts as a router, which strengthens the mesh for your battery sensors. Who should pass: anyone with no Zigbee coordinator and no Hue Bridge. Home Assistant 2026.10.4 does ship a hue_ble integration (local_push) that drives Hue bulbs over Bluetooth, but it only reaches bulbs within range of a Bluetooth adapter or proxy, which suits one lamp, not a house. Also keep each Hue bulb on one controller: a bulb paired to your coordinator leaves the Hue Bridge, and the other way round.
Expect about $20 to $30 for one bulb on Amazon, check the live price. The two-pack runs about $35 to $40, which brings the cost per bulb down a little.
2. ThirdReality ZL1 four-pack
ThirdReality markets the ZL1 for Home Assistant by name, and it is the cheapest way we found to fill a room with Zigbee colour bulbs.
Each ZL1 is an A19 colour bulb rated at 800 lumens, tunable from 2700 to 6500 K, on Zigbee 3.0. ThirdReality states the bulb also works as a Zigbee repeater, and Zigbee2MQTT exposes the same power_on_behavior choices as Hue plus OTA firmware. The four-pack listing names ZHA and Zigbee2MQTT in its title, which matches what we saw in the device definitions. It pairs to any Zigbee 3.0 coordinator with no ThirdReality hub involved.
The ZL1 makes sense for a homelab that already runs Zigbee and wants four rooms lit for the price of one premium bulb. It is the wrong bulb for anyone who wants whites below 2700 K, since Hue goes down to 2200 K and the Aqara T2 to 2000 K. ThirdReality does not publish the wattage on its product page, so we cannot compare running cost with the others. The four-pack runs about $28 to $32 on Amazon, check the live price.
3. Aqara LED Bulb T2 (Thread)
The T2 is the one bulb here that lets you choose the radio. Aqara sells it as a dual Thread and Zigbee bulb, and it ships set to Thread.
Aqara quotes up to 1100 lumens for the T2 family (the GU10 version gives 450), with whites from 2000 to 9000 K and a CRI above 90. That is the widest white range in this guide after LIFX. In Thread mode it is a Matter device, so Home Assistant adds it through the matter integration (local_push) once you have a Thread border router. The OpenThread Border Router app on a ZBT-1 or ZBT-2 stick does that job inside Home Assistant, but a stick running Thread cannot also be your Zigbee coordinator, so Zigbee plus Thread means two sticks. Zigbee2MQTT supports the T2 in Zigbee mode, and the definition we printed shows four power-on choices including restore, plus a power_outage_count sensor.
The catch is getting it into Zigbee mode. Aqara’s FAQ, as reproduced by retailers and the bulb manual, says the bulb is set to Thread by default and is switched to Zigbee from the setup page in the Aqara Home app, which needs an Aqara account. At least one Zigbee2MQTT user reports that the bulb then had to be removed from the Aqara account before it joins a third-party Zigbee network. If your house runs only Zigbee2MQTT or ZHA, budget ten minutes in the Aqara app per bulb, or buy the ThirdReality instead. The T2 suits you if you are building a Thread network for Matter locks and sensors and want bulbs on the same mesh. It has no Wi-Fi, so without a Thread border router or a Zigbee coordinator it does nothing in Home Assistant. Expect about $20 to $25 on Amazon, check the live price. A tunable white T2 costs a little less if you do not need colour, but its whites run only 2700 to 6500 K and Zigbee2MQTT treats it as a separate model.
4. WiZ A19 Full Color (Wi-Fi)
WiZ is the bulb we would hand someone on day one of Home Assistant, because it needs nothing but the Wi-Fi you already have.
The 60 W equivalent WiZ A19 is rated at 800 lumens and 8.8 W. Whites run from 2200 to 6500 K with a CRI of 90 or more, on 2.4 GHz Wi-Fi and Bluetooth. Home Assistant finds WiZ bulbs on the network, and the wiz integration is local_push. Commands go to UDP 38899 on the bulb, and Home Assistant listens on UDP 38900 for the bulb to report changes. Your dashboard updates as soon as someone flips a scene from the WiZ app. The WiZ app has an Allow local communication setting that Home Assistant needs, and the Home Assistant docs say it is on by default.
WiZ fits a new Home Assistant user with no Zigbee or Thread radio, or a rental where you cannot run a coordinator. We would not pick it for anyone with dozens of bulbs on a consumer router, since every WiZ bulb is one more 2.4 GHz client on your Wi-Fi. Buy the Amazon.com listing linked here, since several third-party listings for the same family exist. The three-pack runs about $22 to $27, check the live price.
5. LIFX Color A19 (1100 lumens)
LIFX makes the brightest Wi-Fi A19 in this guide and the widest white range of all seven, which matters in a room lit by one fixture.

The LIFX Color A19 is rated at 1100 lumens with whites from 1500 to 9000 K, over 2.4 GHz Wi-Fi with no hub. The lifx integration talks to each bulb on UDP 56700 and never touches the LIFX cloud. The cost of that design is polling. Home Assistant reads every LIFX bulb on a 10-second timer, so changes made outside Home Assistant can lag on screen, while commands sent from Home Assistant apply at once.
Get the LIFX if you are replacing a bright 75 W bulb in a living room or a kitchen. Look elsewhere if your automations react to state changes made in the LIFX app, because the 10-second lag shows up there. LIFX also sells a Matter version of this bulb. The lifx integration does not need Matter, so either version works for you. Expect about $20 to $30 on Amazon, check the live price.
6. Govee H6008 with LAN control
Govee bulbs are everywhere on Amazon, and the H6008 is one of the few models Home Assistant can control without Govee’s cloud.
The H6008 is an 800 lumen, 9 W colour A19 on Wi-Fi and Bluetooth. The govee_light_local integration supports only models on its published list, and H6008 is on it. Despite its local_push label, it polls each bulb every 30 seconds, so a change made in the Govee app can take up to half a minute to reach your dashboard. Before Home Assistant can see the bulb, you turn on LAN control for each bulb in the Govee Home app. The client library then uses three UDP ports:
- UDP 4001: discovery to multicast 239.255.255.250
- UDP 4002: the bulb replies to Home Assistant
- UDP 4003: commands from Home Assistant to the bulb
All three must pass if your bulbs sit on another VLAN. There is no field to add a Govee bulb by IP address, so discovery has to reach the bulbs, and the last section covers how.
For colour in a lamp or two, the H6008 is the cheap route at under $10 a bulb. It frustrates anyone who wants a full spec sheet, because the Govee product page lists CRI 80 in the table and 90+ in the copy, and shows only 6500 K for colour temperature. The Amazon listing does not print a model number, and we matched it to the H6008 by its 800 lumen two-pack title, so check the box against the Home Assistant list when it arrives. The two-pack runs about $17 to $20, check the live price.
7. KAUF A21 with ESPHome
KAUF ships its bulbs with ESPHome firmware already flashed, which makes it the only pick here where you own the firmware and can change it.
The KAUF bulb runs an ESP8266 with five PWM channels (red, green, blue, cold white, warm white). When it has no Wi-Fi network to join, it opens a hotspot called Kauf Bulb Hotspot for setup, and after that Home Assistant discovers it through the esphome integration, which is local_push over TCP 6053. KAUF says the bulb comes on white when power is applied so it still works from a normal wall switch, and a Kauf Bulb Power On State select in Home Assistant changes that (restore, always on at the last value, always on white, or always off). Firmware 1.7 and later adds DDP, so a WLED controller or xLights can drive the bulb as part of a light show.
KAUF is for the ESPHome user who wants to edit the YAML, or anyone who wants a bulb that keeps working if every vendor app disappears. It is a poor choice for anyone who wants published brightness numbers, because KAUF does not list lumens or a colour temperature range. One more behaviour to know: KAUF documents that the bulb reboots every 15 minutes when it cannot reach Home Assistant, unless you turn on its Kauf Bulb No HASS switch, so set that before you test it away from your server. This is an A21, a little larger than an A19, so check the shade first. Expect about $14 to $20 on Amazon, check the live price.
Why Nanoleaf, Tapo and IKEA did not make it
Three popular names dropped out, and each for a reason that matters in Home Assistant rather than for the bulb’s quality:
- Nanoleaf Essentials Matter A19: the Amazon two-pack is the Wi-Fi version, not Thread
- TP-Link Tapo L530E: local, but Home Assistant needs your TP-Link cloud login
- IKEA KAJPLATS: Matter over Thread, but only EU-base resellers on Amazon US
Nanoleaf sells the Essentials A19 in both Thread and Wi-Fi versions, and the current Amazon listing we checked is the Wi-Fi one. The nanoleaf integration in Home Assistant does not support Essentials bulbs either, so they come in through Matter or, over Thread and Bluetooth, through HomeKit Controller. The Aqara T2 does the Thread job, with Zigbee as the alternative mode. Tapo bulbs work through the tplink integration (local_polling), but newer Tapo and Kasa devices need your TP-Link account email and password in Home Assistant to authenticate locally, which is a dependency we would rather not have on a lamp.
What to check before you buy smart bulbs
Most bulb regret comes from buying for features and finding out about the radio later. Run through these in order:
- Check which radio your Home Assistant box already has
- Count your 2.4 GHz Wi-Fi clients before adding ten bulbs
- Decide what a bulb does after a power cut
- Keep each wall switch on, or fit a smart switch
- Confirm a Thread border router exists before buying Thread
- Match the base and size to the fixture
The power-cut question is the one people skip. A smart bulb behind a wall switch that someone flicks off is a bulb Home Assistant cannot reach, and when the switch comes back on the bulb follows its power-on setting. The three Zigbee picks let you set that in Zigbee2MQTT, so a restored bulb comes back at its previous state instead of full white at 3 a.m. If wall switches are the real problem, a smart switch in smart-bulb mode fixes it, and the box running Home Assistant should have room for the radio. Our Home Assistant mini PC guide covers that hardware.
If you have not picked a Zigbee stack yet, read our ZHA vs Zigbee2MQTT comparison first, since the power-on and OTA settings above are Zigbee2MQTT names. For a fresh install, our Home Assistant on Ubuntu guide gets the core running in a container. The same local-only test runs through our thermostat picks and our water leak sensor and shutoff valve guide if lighting is the first of several upgrades.
What tripped us up
Our plan for this guide had a Nanoleaf bulb as the Thread pick. Its Amazon title says Matter A19 and nothing else, and only the full listing reveals the two-pack is the Wi-Fi model, so we swapped in the Aqara T2, whose title names Thread and Zigbee. Read the full listing for any Matter bulb, because Matter runs over Wi-Fi or Thread and box fronts rarely say which.
Our own script caused the second snag. The first run of the Zigbee2MQTT check printed empty exposes for every bulb, because current zigbee-herdsman-converters builds exposes only after a definition goes through prepareDefinition(). If you read device definitions yourself, run them through that function first, or you will think a bulb exposes nothing at all. The fixed run is the output shown under How we checked local control.
Ports to open for bulbs on an IoT VLAN
Putting bulbs on their own VLAN is common practice in a homelab, and Wi-Fi bulbs then need firewall rules between Home Assistant and that VLAN. Zigbee bulbs need none when the coordinator is a USB stick on the Home Assistant box. A network (Ethernet or PoE) coordinator on another VLAN needs a rule from Home Assistant to that coordinator. Thread bulbs behind a border router stick on the Home Assistant box need none either. With an Apple TV, HomePod or Nest Hub as the border router, keep that device on the Home Assistant VLAN. The Home Assistant Matter docs say Matter relies on local IPv6 and mDNS moving freely between them. We pulled the ports from the client libraries Home Assistant 2026.10.4 installs:
pywizlight/bulb.py:31:PORT = 38899
pywizlight/push_manager.py:15:LISTEN_PORT = 38900
lifx/network/discovery/mdns/discovery.py:806: port = srv_endpoint[1] if srv_endpoint else 56700
homeassistant/components/lifx/coordinator.py:65: update_interval=timedelta(seconds=10),
govee_local_api/controller.py:41:BROADCAST_ADDRESS = "239.255.255.250"
govee_local_api/controller.py:42:BROADCAST_PORT = 4001
govee_local_api/controller.py:43:LISTENING_PORT = 4002
govee_local_api/controller.py:44:COMMAND_PORT = 4003
aioesphomeapi/log_reader.py:22: parser.add_argument("--port", type=int, default=6053)
kasa/discover.py:420: DISCOVERY_PORT = 9999
kasa/discover.py:426: DISCOVERY_PORT_2 = 20002
A second pass read the Govee polling timer, whether the Govee setup form takes an address, and the two TCP ports python-kasa uses for bulbs:
homeassistant/components/govee_light_local/const.py:13:SCAN_INTERVAL = timedelta(seconds=30)
homeassistant/components/govee_light_local/coordinator.py:42: update_interval=SCAN_INTERVAL,
govee_light_local strings.json: no host field
kasa/transports/klaptransport.py:95: DEFAULT_PORT: int = 80
kasa/transports/xortransport.py:44: DEFAULT_PORT: int = 9999
Turned into rules, that gives the table below. Direction matters, because WiZ bulbs push changes to Home Assistant unprompted and Govee bulbs answer status requests on a separate port:
| Bulb | Home Assistant to bulb | Bulb to Home Assistant | Discovery |
|---|---|---|---|
| WiZ | UDP 38899 | UDP 38900 | DHCP watch, UDP 38899 |
| LIFX | UDP 56700 | Replies only | UDP broadcast on 56700, DHCP watch, mDNS (_lifx._udp) |
| Govee (LAN) | UDP 4003 | UDP 4002 | Multicast 239.255.255.250 on UDP 4001 |
| KAUF (ESPHome) | TCP 6053 | Same connection | mDNS |
| Hue via Bridge | HTTPS to the bridge | Same connection | mDNS (_hue._tcp) |
| Tapo / Kasa bulbs | TCP 80 (Tapo, newer Kasa) or TCP 9999 (older Kasa) | Replies only | UDP 9999 and 20002 |
Broadcast and multicast discovery do not cross VLANs on their own. For WiZ, LIFX and ESPHome bulbs, add each one by IP address in Home Assistant, or run an mDNS reflector on the router for the ones that announce over mDNS. Govee needs a different fix. Its setup form has no address field, and its discovery uses 239.255.255.250 on UDP 4001, which an mDNS reflector does not forward. Either give the Home Assistant host a network interface on the IoT VLAN, or relay that multicast group with a UDP multicast relay or IGMP proxy on the router. Give the bulbs DHCP reservations as well, because an integration added by IP breaks quietly when the lease changes. If all of that sounds like work, it is the strongest argument for the Zigbee and Thread picks, which keep the bulbs off your IP network entirely.





