zigbee2mqtt.io: the device catalogue that a bridge project generates for you
📘 Zigbee2mqtt documentation
At a glance
- What is it?
- The zigbee2mqtt.io repository holds the documentation site for the Zigbee2MQTT bridge, and its most interesting part is not the prose but the generator that writes a page per supported device from the converters repository. It is a VuePress site with a TypeScript docgen pipeline, and the device pages are largely machine written with a hand maintained notes section inside each one.
- Who is it for?
- zigbee2mqtt.io fits a Zigbee user who wants to check whether a specific device is supported and how it behaves before buying it, and it fits a Zigbee2MQTT contributor who wants to work on the documentation or on the generator rather than the bridge itself.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A documentation site with a generator behind it
The repository is described in one line as containing the Zigbee2MQTT documentation, and it says it is based on VuePress v2. The primary language on the project record is TypeScript, which is the first hint that this is not a folder of Markdown and screenshots.
The architecture section describes the layout, and each entry has a job. The docgen directory holds scripts to test and generate the device pages. The docs directory holds the current documentation. Inside docs/.vuepress there are VuePress enhancements such as stylesheets. The public directory holds static assets. The supported-devices-component is a Vue.js component that renders the devices overview page. And there are three top level TypeScript files for configuration: navbar.ts for the top navigation, sidebar.ts for the sidebars by individual section such as Guide, and vuepress.config.ts, the VuePress config file itself.
That is a well organised static site, and the interesting part is the relationship between the docgen directory and the docs directory.
The build and deploy badge in the README points at a GitHub Actions workflow called build-deploy, so the site is published automatically rather than by a person uploading it somewhere.
For a reader, the practical consequence is that the site is a product of a pipeline, and a pipeline has different failure modes than a wiki. A device page can be wrong because the data was wrong, and the person who knows about the device may be someone who has never opened the documentation repository at all.
Device pages are generated, and the notes section is the human part
The docgen section explains the mechanism, and it is the part of the repository that makes it more than a static site.
The docgen-scripts help to generate and update the individual device pages under /docs/devices/. The source of truth is the zigbee-herdsman-converters repository, which exposes a list of supported devices, and that list is used for generation. The same run also updates the devices list used by the supported-devices overview page.
Then comes the part that makes the design sensible. The Notes section of each page is written by hand and does not come from zigbee-herdsman-converters. That section gets preserved and can be edited.
So the split is: everything the converters project knows about a device, the model, the manufacturer, the supported features, comes from the upstream data and is regenerated. Everything a human knows that the upstream data cannot express, the quirks, the workarounds, the pairing notes, is written into a preserved block that survives regeneration.
That is a good pattern and it is worth understanding precisely because it explains the shape of the pages you see on the site. A device that has just gained support in the converters project appears on the site with a complete, accurate, machine written feature list and an empty notes section, and the notes fill in as people find the things that only a user can discover.
It also means the same information lives in two systems with different lifecycles. The upstream list changes when a converter is merged. The notes change when someone learns something the hard way and bothers to write it down.
Running the generator and the two test scripts
Docgen is written in TypeScript, so the documentation says you need a recent version of Node.js and NPM, and gives the three commands:
# One-time initialize package-lock.json otherwise 'pnpm i' may fail due tu dependencies
pnpm install
# Install dependencies
pnpm i --frozen-lockfile
# Run docgen
pnpm run docgenThe comment on the first command explains why it exists: the package-lock.json has to be initialised once, otherwise the frozen lockfile install may fail because of dependency issues. That is the kind of note that only appears in a repository where somebody hit it.
Two test scripts are named for the documentation, and both are about the generated output rather than about the prose. check-device-images checks for missing device images, and check-links checks for broken internal links. The attention note attached to the second one is the important part: check-links iterates over the generated VuePress files, so you have to build the page first.
That is a sensible design, because link checking against generated output is what catches a device page that references a section that no longer exists, which is exactly the class of error that a generator introduces and a human writing prose would not.
The package manifest shows the wider script set. There are several image-related scripts, download-missing-device-images, move-missing-device-images, copy-missing-device-images and prepare-missing-device-images, all running the same TypeScript entry point with a different verb. There is a pretty:write and pretty:check pair running Prettier, and a test script that runs the docgen tests. The docgen script itself is ts-node docgen/index.ts followed by pretty:write, so generation is always followed by formatting.
The dev mode deliberately leaves out most of the site
The development workflow is where the scale of the catalogue becomes visible, because the solution is to exclude most of it.
Use Node.js 20 for building VuePress, since other versions are not officially supported. The commands for that are a switch to node 20 for nvm or nvm-compatible tool users, and then pnpm i --frozen-lockfile to install dependencies.
The dev mode is described as excluding the huge amount of device pages, which slows down the build process drastically. The reason the dev script sets EXCLUDE_DEVICES=yes in the manifest is now obvious: the device pages are the bulk of the site, and they are the part a documentation author working on prose never needs to see. The dev:devices script is the counterpart, and it raises the Node heap with NODE_OPTIONS set to a max old space size of 12000 before running vuepress dev, which is a large heap allowance for a page set that size.
Two escape hatches make the workflow practical for a contributor who is working on one device. You can include a single device by supplying the INCLUDE_DEVICE variable with the device's filename from the /docs/devices folder, without the .md extension, using cross-env, and the example given is a TS011F_plug_1. And you can change the development server port when the default 8080 is taken, with DEV_PORT set to a number such as 15080.
Both are small conveniences and both exist for the same reason. A contributor fixing a typo in one device's notes should not have to wait for a build of thousands of pages, and the INCLUDE_DEVICE route is the direct answer to that.
The Docker route and the difference between dev and build
There is a container route, and the documentation frames it as an alternative to installing Node locally.
$ docker run --rm -v $PWD:/app -u $UID -ti node:18-slim bash
node@87e1438ef553:/$ cd /app
node@87e1438ef553:/app$ pnpm i --frozen-lockfile
node@87e1438ef553:/app$ pnpm run devThe three flags do the work. The volume mount puts your checkout at /app inside the container, running as your own user with -u $UID so the files you create are yours rather than root's, and the interactive bash shell keeps it open so you can run the pnpm commands inside.
The container runs Node 18 while the VuePress section asks for Node 20, which is a small inconsistency in the documentation. Since the build is pinned through a .nvmrc in the repository listing, using the version the project asks for is the safer choice, but the Docker recipe is the documented fallback for people who would rather not manage a Node installation.
The production build is a single command:
# Run vuepress build
pnpm run buildand the build artefact goes to the dist directory. The build script carries the same 12000 megabyte heap allowance as the devices dev script, which is a reasonable indication of how much memory the full device set takes to compile.
So there are three modes with three different costs. A full build produces the whole site and takes real memory. The plain dev mode excludes the device pages and is fast. And the dev mode with a single device included is the middle path for the common case of fixing one device's notes.
Where this repository is the wrong place to look
Three situations rule it out.
The first is if you are looking for the bridge software. The code that talks to your Zigbee radio, the one that presents devices to Home Assistant and to MQTT, lives in the separate Zigbee2MQTT project, and this repository is only its documentation. The site is where you read, the project is where you run.
The second is if you want authoritative compatibility information. Because the device pages are generated from the converters repository, they describe what the software believes it supports. The notes sections add human knowledge, but they are maintained per device by whoever bothered, and the project does not describe a review process for them. A device with an empty notes section is not a device with no quirks, it is a device nobody has written about yet, and treating the two as the same is how you end up debugging something that was already known.
The third is if you are looking for the current state of a specific device. The site is regenerated from upstream data, so a device that gained support in the converters project may not be on the site until the docgen run and the site build have both happened. The repository has no GitHub releases, so there is no version tag to point at, and the repository is not archived with the last push on 2026-10-19, so the content moves continuously.
The reasonable use is narrower and more useful: to check whether a device is in the catalogue, to read what the machine knows about it, and to add the one piece of information that only you learned. That is what the preserved Notes section is built for, and it is a better contribution than a documentation fix that the generator would overwrite.
Editorial conclusion
zigbee2mqtt.io fits a Zigbee user who wants to check whether a specific device is supported and how it behaves before buying it, and it fits a Zigbee2MQTT contributor who wants to work on the documentation or on the generator rather than the bridge itself. It is the wrong tool if you are looking for the bridge software, since the code that talks to your radio lives in the separate Zigbee2MQTT project, and it is the wrong place to look for hand written compatibility advice, because the notes sections are individually maintained and therefore uneven. Before contributing, run the docgen tests, read the check-links script, and remember that the device pages are regenerated from upstream data, so editing a generated page directly will be overwritten.
Frequently asked questions
What is the zigbee2mqtt.io repository?
It is the repository for the Zigbee2MQTT documentation site, built on VuePress v2, with the site published at zigbee2mqtt.io. It contains the docs directory, the VuePress configuration files for the navbar and sidebars, and a docgen directory with TypeScript scripts that generate the per-device pages.
How are the Zigbee2MQTT device pages generated?
The docgen scripts use the supported device list exposed by the zigbee-herdsman-converters repository, generating the pages under /docs/devices and updating the list used by the supported-devices overview page. The Notes section of each page is written by hand and preserved across regeneration, so human knowledge survives a rebuild.
How do I run the docgen scripts?
You need a recent version of Node.js and NPM. Run pnpm install once to initialise the lockfile, then pnpm i --frozen-lockfile, then pnpm run docgen, which runs ts-node docgen/index.ts and follows it with the Prettier write step.
How do I work on one device page in the Zigbee2MQTT docs?
Run the dev mode with the INCLUDE_DEVICE variable set to the device filename without the .md extension, using cross-env, for example npx cross-env INCLUDE_DEVICE=TS011F_plug_1 pnpm run dev. The plain dev mode excludes device pages entirely because they slow the build down drastically, and you can set DEV_PORT if port 8080 is taken.
Is the Zigbee2MQTT documentation still being updated?
The last push to the repository was on 2026-10-19 and it is not archived, with a build and deploy workflow publishing the site automatically. The repository has no GitHub releases, the licence is GPL-3.0, and the build is expected to use Node.js 20 with pnpm at version 10.12.1.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/koenkk-zigbee2mqtt-io)