Skip to content

Blog

Sunsetting support for IDF 4.x

At the beginning of this year, we made the transition from IDF 4.4 to IDF 5.1; this was a major upgrade and many changes were necessary within ESPHome to achieve this.

A long-standing (but largely undocumented -- until now) rule of the project is that we only support one major version of ESP-IDF at a time. While it's technically possible to support multiple major versions, doing so introduces some significant challenges:

  • Code is more messy, complex and difficult to maintain
  • Changes are more complex to test
  • CI run durations are (significantly) longer

As you may know, ESPHome supports using both ESP-IDF and Arduino as frameworks for projects built with Espressif's ESP32 family of microcontrollers. Up to this point, we have been using Arduino 2.x, which is built on IDF 4.x; this effectively means we are still using (and supporting) two different major versions of IDF. In the next release of ESPHome, we'll update the default Arduino framework version to 3.x, which is built on IDF 5.x; this means we will no longer need to maintain compatibility with IDF 4.x.

Just prior to switching the default IDF version to 5.1, we were running our tests against both major versions -- but this meant that our CI took over ten hours to complete for one single release! This isn't tenable in the long term and, after making IDF 5.1 the default, we stopped running our tests against IDF 4.x in an effort to get our CI run duration back down to "normal"...which is still often over five hours now. (We are looking for ways to improve this, but that's a topic for another day.)

Beyond this, maintaining a codebase with support for both major versions is just plain messy and complex. As Espressif releases more and more new SoCs/microcontrollers, support for them won't be backported into IDF 4.x, which means that you won't be able to use those new microcontrollers with IDF 4.x, anyway. Further, as new features and functionality are introduced into IDF 5.x, they also won't be backported to IDF 4.x, so you won't be able to take advantage of these.

Last, but not least, we've made a number of optimizations to reduce the memory (RAM and flash) footprint of ESPHome in this (June) release; if you were experiencing issues with IDF 5.x before, please try it again as you're more likely to be able to use it now.

With these points in mind, we are officially sunsetting support for IDF 4.x in ESPHome. If you have kept your project(s) back on IDF 4.x, you can continue to use versions of ESPHome prior to the July 2025 release, but you won't be able to upgrade beyond that version. We encourage everybody to move to IDF 5.x -- specifically, in the June release, we have switched the default IDF version to 5.3.2. In addition, we'd like to call out that we are working to accelerate the adoption of new IDF versions; this helps us add support for new Espressif microcontrollers more quickly than we've been able to in the past.

*.*_SCHEMA deprecations

In order to align all of the top level platform components (listed below), we are deprecating the *_SCHEMA constants that are present. Some examples are SENSOR_SCHEMA, SWITCH_SCHEMA and so on.

Each entity platform component has a matching *_schema(...) function which takes the class type and common schema defaults as arguments. There are plenty of examples in the ESPHome codebase of these.

This will become a breaking change in ESPHome 2025.11.0, set to release around the 19th of November 2025. The breaking PRs will be merged right after the 2025.10.0 release goes out around the 15th of October 2025.

If you are a maintainer of external_components that use these constants, please update them to use the new *_schema(...) functions. If you are a user of external_components and see the warning in your install logs, please reach out to the maintainers of those components and ask them to update their code.

external_components are able to import the ESPHome version into their python file in order to support older versions in the cases where the relevant *_schema(...) function was not added yet.

List of affected components

  • alarm_control_panel
  • binary_sensor
  • button
  • climate
  • cover
  • datetime
  • event
  • fan
  • lock
  • media_player
  • number
  • select
  • sensor
  • switch
  • text
  • text_sensor
  • update
  • valve

Reference Pull Requests

About the removal of support for custom components

ESPHome's "custom component" mechanism was a holdover from Home Assistant's feature by the same name. It existed before external components and offered a way to "hack in" support for devices which were not officially supported by ESPHome.

Why were custom components removed?

There are several reasons for this change.

  • Custom components are very fragile:

    • There is no validation. You can easily configure a custom component incorrectly and there will be no warning.
    • Types are not checked. You might incorrectly pass a variable of an incorrect type or unit to a custom component resulting in compiler errors, unexpected behavior and/or crashes.
    • Custom components are difficult to use. You have to manually copy all of the custom component's files into just the right location on your system or else you will receive compiler errors and the component won't work.
    • Custom components lack flexibility and almost always require C++ code changes when you want them to work even slightly differently than the original author intended/designed. For example, a simple change of input units (cm to m, for example) could require significant changes to the C++ code, depending on how the original author designed the custom component.
  • External components initially require a bit more effort by the developer but are ultimately more robust and are easier to use and share:

    • Just like any other ESPHome component/platform:
      • They are configured entirely in YAML.
      • Their YAML configuration is validated.
    • They do not require the user to:
      • Manually copy files onto their system.
      • Touch/edit any C++ code.
    • They tend to be more flexible since they are configured in YAML (as opposed to editing C++ code to make changes).

What's the difference?

Custom components are typically (more or less) just the runtime part of an ESPHome component/platform. On the other hand, external components are just like any other ESPHome component -- the only difference is that they are external in the sense that they are not "officially" a part of ESPHome.

In terms of implementation, custom components just lack the Python part of an ESPHome component, specifically:

As such, most custom components can be made into external components simply by adding the required Python parts to make the custom component into a proper, complete ESPHome component.

What's next?

We encourage all custom component developers to extend their custom component(s) into proper external components; doing so will make your custom component easier to share and use. As you do so, be sure to have a look at the the sections above as it walks through ESPHome (component) architecture. In addition, it's often helpful to take a look at other, similar components and adapt them to fit the needs of your custom component. For common hardware devices such as sensors, this is often a reasonably trivial exercise and we are happy to help you along!

Hello Developers!

Welcome to the first post of this new ESPHome Developer Documentation. This is a place where you can find all the information you need to start developing for ESPHome. This website will cover everything you need to create components and how to structure your code so that it will be easy to maintain and understand.