Z-Wave JS UI

Full-featured Z-Wave control panel and MQTT gateway

Home Automation ★ 1.2k stars Medium setup MIT

Z-Wave JS UI is a web interface and MQTT gateway built on the Z-Wave JS driver for managing Z-Wave networks. It exposes devices to home automation platforms and provides a control panel for configuration.

Key features

  • Z-Wave network management
  • MQTT gateway
  • Web control panel
  • Firmware update support

Pros & cons

Strengths

  • Excellent Z-Wave support
  • Integrates with Home Assistant

Trade-offs

  • Requires a Z-Wave controller
  • Z-Wave only

Z-Wave JS UI replaces

Last reviewed Sep 13, 2026 · 805 words

Buy the stick first, and back up the keys second. Z-Wave JS UI is the control panel for a Z-Wave network, and the network exists in two places: the controller's non-volatile memory, which holds every paired device, and four security keys that Z-Wave JS UI generates and stores in its settings. Lose the container's volume without a copy of those keys and every S2-secured lock, sensor and dimmer must be excluded and re-paired by hand. That warning aside, this is the best way to run Z-Wave on a self-hosted stack, and it is what Home Assistant's own integration is built on.

Hardware: an 800-series USB controller

Z-Wave needs a radio, and the radio is a USB stick. An 800-series controller such as the Zooz ZST39 or Aeotec's Z-Stick 7 and 10 gives you the current Long Range and S2 features; older 500-series sticks still work. Pass it into the container by its stable path, /dev/serial/by-id/usb-..., never /dev/ttyUSB0, which changes after a reboot with two USB devices attached. Z-Wave runs at 908 MHz in North America and 868 MHz in Europe, so a stick bought abroad is a paperweight, and while it is less sensitive than Zigbee to USB 3 interference, a short USB extension cable to move it away from the host is still cheap insurance.

The compose file that most people run

services:
  zwave-js-ui:
    image: zwavejs/zwave-js-ui:latest
    devices:
      - /dev/serial/by-id/usb-Zooz_800_Z-Wave_Stick_530-if00:/dev/zwave
    volumes:
      - ./store:/usr/src/app/store
    ports:
      - "8091:8091"   # web UI
      - "3000:3000"   # websocket for Home Assistant
    environment:
      - TZ=Europe/London
    stop_grace_period: 30s
    restart: unless-stopped

Port 8091 is the panel; port 3000 is the Z-Wave JS websocket server, and the checkbox to enable it lives in the settings page. Set the serial port to /dev/zwave on first launch, let the UI generate the S0 and three S2 keys, then copy them out of the settings screen into your password manager. The store/ volume holds config, keys, the device cache and NVM backups, and it is the only thing to back up. The stop_grace_period line matters: the driver needs a few seconds to close the serial port cleanly or the stick can come back in a confused state.

Home Assistant talks to it over the websocket, not MQTT

Two ways to reach an automation platform. Home Assistant uses the Z-Wave JS integration pointed at ws://host:3000 and gets every device and value natively; this is the intended path and the one with the best entity naming. The MQTT gateway is for everything else: openHAB, Node-RED, or a custom script, publishing to a Mosquitto broker with Home Assistant discovery messages if you want. Running both at once is supported but doubles the surface area for confusion, so pick one. The panel itself is worth having even with HA doing the automation: device interviews, firmware updates over the air, node health maps, and the ability to set configuration parameters HA does not expose all live here, and none of it is in HA's own UI.

Add-on or standalone container

Home Assistant OS offers a Z-Wave JS UI add-on that is this same software in a wrapper. Use it if your whole setup is HAOS on one box. Run the standalone container when Home Assistant lives in Docker or on a different machine, when you want to restart HA without dropping the Z-Wave network, or when you also run Zigbee2MQTT and prefer both radio gateways as ordinary services on the same host. Keeping radios out of the HA process is the pattern I recommend; the first-month Home Assistant guide explains why HA restarts are frequent early on.

A note on the old name

The project was called zwavejs2mqtt until 2022, and forum posts, compose snippets and screenshots under that name still describe the same software; the MQTT part became optional and the name changed to match. The zwavejs/zwavejs2mqtt image still resolves but is a redirect, so use the current one.

What I'd do

An 800-series stick on a USB extension, the compose file above on the same host as Mosquitto and Zigbee2MQTT, keys copied to the password manager before pairing the first device, and Home Assistant connected over the websocket. Take an NVM backup from the panel after every batch of new devices and keep the store/ directory in the nightly backup. It replaces a SmartThings hub outright for Z-Wave, with 256 MB of RAM and no cloud, and it has been the least troublesome piece of my home automation stack for years.

Compare Z-Wave JS UI

19 head-to-head comparisons.

Similar home automation apps