Library / SDK
HomeSpan/HomeSpan avatar
HomeSpan/HomeSpan

HomeSpan: turning an ESP32 into a HomeKit accessory from the Arduino IDE

HomeKit Library for the Arduino-ESP32

2,182 stars202 forksC++MIT

At a glance

What is it?
A C++ library that implements Apple's HAP-R2 protocol on Espressif chips with no bridge, no hub software and no cloud. Its real strength is a status LED that tells you exactly which pairing state the device is stuck in.
Who is it for?
HomeSpan is the right library when you want one device on your network rather than a hub bridging a fleet of them, and the Arduino IDE workflow is a genuine advantage over configuring a protocol stack by hand. It also asks for something in return: a HomePod or Apple TV on the network, because HomeKit will not operate properly without one, and the library states that plainly.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 27 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library actually implements

HomeSpan is a C++ library for the Arduino IDE that creates ESP32-based HomeKit devices. It provides a microcontroller-focused implementation of Apple's HomeKit Accessory Protocol Specification Release R2, and it pairs directly to HomeKit over your home WiFi network without external bridges or components.

That last sentence is the entire pitch, and it is worth being precise about what it rules out. There is no separate bridge box, no software running on a server, no cloud service. The ESP32 speaks HAP-R2 itself. What you get in return is that the device depends on HomeKit's own architecture, which brings its own requirement: Apple's HomeKit architecture requires a Home Hub, either a HomePod or an Apple TV, for full and proper operation of any HomeKit device. The README is unusually direct about this, stating that use of HomeSpan without a Home Hub is not supported.

The library is MIT licensed, written in C++, on a master branch, not archived, last pushed on 2026-09-15. It has 2,170 stars and only 9 open issues, which for a library with this many users is a small number.

The current production release is 2.1.8, dated 26 APR 2026 in the README's update section and published on 2026-04-27. It claims 100 percent HAP-R2 compliance and dozens of integrated HomeKit services.

The hardware and core version requirements table

The README publishes a requirements table, and two rows in it will decide whether your particular board can work.

The supported chips are ESP32, S2, S3, C3, C5 and C6. The footnote on that row says HomeSpan cannot be run on an ESP-8266, though an ESP-8266 can be used as a remote sensor alongside HomeSpan's SpanPoint functionality. So if you have a pile of ESP-8266 boards, this is not the library for them.

The core requirement is the row people get wrong. The minimum required Arduino-ESP32 Core is 3.3.0, and the latest core fully tested with HomeSpan is 3.3.8. The footnote on the minimum is explicit that the current production release will fail to compile under any Arduino-ESP32 Core release earlier than that. Another footnote notes HomeSpan does not support alpha, beta or pre-release candidates of the core, because testing is only done on production releases.

The memory row is the other one. The minimum flash partition size is 1.9MB, and the recommended partition scheme is Minimal SPIFFS with a 1.9MB app and OTA. The footnote qualifies that recommendation as assuming a device with 4MB of flash, and notes that for devices with 8MB or more you may choose any partition scheme providing at least 1.9MB of app space and 1.9MB of OTA space if using OTA.

Those three numbers, chip family, core version and partition size, are what you check before writing any code.

Service-centric configuration and the two operating modes

The design claim the README leads with is a unique service-centric approach to creating HomeKit devices, and it is the part of the API that takes adjusting to.

Rather than describing your device as a collection of things, you describe the services it offers, and the library assembles the accessory. That maps onto HomeKit's own model, where the Home app shows services like a lightbulb or a fan inside an accessory, and it means a device offering both a light and a fan is expressed as two services rather than two custom objects.

The library operates in either Accessory or Bridge mode. A standalone device presents itself as one accessory with its own services. A bridge mode device presents several accessories from one ESP32, which is how you put a handful of unrelated relays behind a single network participant and a single pairing.

Pairing supports Setup Codes or QR Codes, which covers both the older eight-digit code flow and the newer camera-based one. Connectivity works over both WiFi and Ethernet, and the library supports dual-stack use of both IPv4 and IPv6 addresses.

Underneath the configuration sits a validation layer. The README lists built-in database validation to ensure your configuration meets all HAP requirements, which means a malformed characteristic or an invalid attribute range is caught at compile time or immediately after boot rather than producing a device that silently fails to pair.

Hardware classes that save you from writing drivers

The developer-facing feature list is mostly a list of peripherals the library has already handled, and this is where a lot of the value sits for someone who would otherwise write driver code.

There are dedicated classes that use the ESP32's 16-channel PWM peripheral for LED brightness including auto-fading, and for servo motors. Push button and toggle switch handling supports single, double and long presses, and works with physical buttons connecting an ESP32 pin to either ground or VCC, as well as touch pads on chips that support them. There is integrated access to the ESP32's on-chip Remote Control peripheral for generating IR and RF signals, which is the fast path to an infrared-controlled device.

Beyond that: classes for one-wire and two-wire addressable RGB LEDs and LED strips, classes for stepper motors that run smoothly in the background without interfering with HomeSpan, and a class for direct point-to-point communication between ESP32 devices using ESP-NOW. That last one is the interesting case, because ESP-NOW lets two boards talk without either being on the network.

Version 2.1.7 added a WS2801_LED class for two-wire addressable LEDs, using the SPI bus, with a worked 25-pixel example added to the Pixel tutorial sketch. Version 2.1.6 added ESP32-C5 support, which required adding WiFi band information to log output because the C5 supports both 2.4 GHz and 5.0 GHz.

The status LED as the project's best idea

The most useful change in the recent releases is a rework of how the library reports its own state, and it is worth understanding because it is the difference between a device that works and a device you spend an evening debugging.

Version 2.1.8, the current release, introduced a new HS_STATUS enum value called HS_CONNECTED. It reflects a fully operational state: connected to a network, paired to HomeKit, and maintaining one or more secure connections to HomeKit. The status LED is steady on in that state. The same release modified HS_PAIRED to reflect a potential no-response state, meaning connected and paired but with no open secure connections yet, shown as an inverted double blink.

Alongside the LED patterns, the release added a `std::pair<HS_STATUS,uint32_t> homeSpan.getStatus()` method returning the current status and how many seconds have passed since HomeSpan first changed into it, plus a `homeSpan.resetStatusDuration()` method. The README points out that getStatus is thread-safe and lets you poll from the main loop, which is an alternative to `homeSpan.setStatusCallback()`, and that callback only fires when the status changes.

The documentation for this was rewritten in the same release, including an example of using getStatus to reboot the device if it has lost secure HomeKit connections for an extended period, and a table of every LED pattern.

Two earlier releases tell you about the project's pace. 2.1.7 landed on 2026-01-01 and bumped the minimum core from 3.1.0 to 3.3.0. 2.1.6, from 2025-10-26, moved OTA password storage from MD5 to SHA256 hashing to match the ArduinoOTA library protocol, with the compatibility handling that SHA256 is used only under core 3.3.2 or greater and MD5 otherwise.

The tutorial ladder and what an end user gets

The examples directory is numbered in a way that makes it read as a course, and the ordering is the curriculum. The requirements it imposes, straight from the README table, are these:

text
ESP32, S2, S3, C3, C5, and C6
3.3.0
3.3.8
Minimal SPIFFS (1.9MB APP with OTA)
HomePod or Apple TV

The directory listing runs from 01-SimpleLightBulb and 02-TwoSimpleLightBulbs through 03-CeilingFanWithLight and 04-AdvancedCeilingFan, then 05-WorkingLED and 06-DimmableLED, before reaching naming, bridges, message logging, RGB LEDs, service names, service loops and target states. The later numbers cover emulated and real push buttons, programmable switches, linked services, saving status, the Web Log, the accessory identifier and TLV8 characteristics.

That ordering is a fair description of how hard this is. A dimmable lightbulb is example 6, and anything involving byte-level characteristic encoding is example 22. If your first HomeKit device is a single relay, you are looking at the first handful; if it is a thermostat with temperature and humidity characteristics, you are in the back half of the list.

There is a second audience the README addresses separately. The end-user features are an embedded WiFi access point and web interface that lets a non-developer set their own home WiFi credentials and create their own HomeKit pairing setup code, plus a status LED and control button that can force-unpair the device, perform a factory reset and launch the WiFi access point. There is also a standalone End-User Guide. The idea is that you flash a device, hand it to someone, and they onboard it themselves without you.

For the developer, the documentation set includes a Serial Monitor command line with info, debugging and configuration commands, real-time diagnostics that show every underlying HomeKit action, and a Web Log for user-defined messages.

Editorial conclusion

HomeSpan is the right library when you want one device on your network rather than a hub bridging a fleet of them, and the Arduino IDE workflow is a genuine advantage over configuring a protocol stack by hand. It also asks for something in return: a HomePod or Apple TV on the network, because HomeKit will not operate properly without one, and the library states that plainly. Before ordering hardware, check the two numbers that decide whether your board works at all, which are the minimum Arduino-ESP32 core of 3.3.0 and the 1.9MB minimum flash partition size. Then start at examples/01-SimpleLightBulb and work forward, because the service-centric model the library is built on does not read like any other Arduino API and the tutorial sketches are the fastest way to acquire it.

Frequently asked questions

Can I build a smart home using ESP32?

Yes, within limits that are worth checking first. HomeSpan implements HomeKit Accessory Protocol Release R2 directly on ESP32, S2, S3, C3, C5 and C6 chips, so a single board pairs directly to HomeKit with no external bridge. It needs Arduino-ESP32 Core 3.3.0 or newer, a minimum 1.9MB flash partition, and a HomePod or Apple TV on the network, since HomeKit does not operate without a Home Hub.

Can HomeSpan run on an ESP-8266?

No. The README states HomeSpan cannot be run on an ESP-8266, though one can be used as a remote sensor together with HomeSpan's SpanPoint functionality. Supported chips are the ESP32, S2, S3, C3, C5 and C6 families.

What is the difference between Accessory mode and Bridge mode in HomeSpan?

A device in Accessory mode presents itself to HomeKit as a single accessory with the services it offers. A device in Bridge mode presents multiple accessories from the same ESP32, so several unrelated relays or accessories can sit behind one network participant and one pairing.

How do I update a paired HomeSpan device over the air?

Over-the-air updates are supported, and password hashing for them moved from MD5 to SHA256 in version 2.1.6 to match the ArduinoOTA library protocol. If you set the OTA password in your sketch with homeSpan.enableOTA(char *pwd) the new hashing is automatic. If you entered the password through the Serial Monitor O command instead, you need to re-enter it so HomeSpan can store it as SHA256.

Official sources

  1. HomeSpan/HomeSpan on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/homespan-homespan.svg)](https://hysenlabs.com/projects/homespan-homespan)