Skip to content

Blog

Trigger Trampolines Eliminated with build_callback_automation

Common entity trigger classes have been replaced with lightweight forwarder structs that fit inline in the callback system. The new build_callback_automation() API eliminates per-trigger object allocations. Several entity callback signatures have also changed to pass state as an argument.

This is a breaking change for external components in ESPHome 2026.4.0 and later.

Application Name and Friendly Name Now Return StringRef

App.get_name() and App.get_friendly_name() now return const StringRef & instead of const std::string &. Most code compiles unchanged because StringRef provides .c_str(), .size(), .empty(), and implicit conversion to std::string. However, binding the result to const std::string & silently creates a heap-allocated temporary — update these references to const auto & to avoid the allocation.

This is a breaking change for external components in ESPHome 2026.3.0 and later.

call_loop(), mark_failed(), and call_dump_config() Are No Longer Virtual

Component::call_loop(), Component::mark_failed(), and Component::call_dump_config() are no longer virtual methods. External components that override any of these methods must remove them entirely and move logic to loop() or dump_config(). This saves 800+ bytes of flash globally from vtable elimination.

This is a breaking change for external components in ESPHome 2026.3.0 and later.

get_loop_priority() Now Conditionally Compiled with USE_LOOP_PRIORITY

The get_loop_priority() virtual method on Component is now only available when USE_LOOP_PRIORITY is defined. This define is only set on RP2040, the only platform where loop priority has an effect. External components that override get_loop_priority() must guard the override with #ifdef USE_LOOP_PRIORITY.

This is a breaking change for external components in ESPHome 2026.3.0 and later.