ESP8266 Build Optimizations: Serial and Waveform Code
ESP8266 builds now exclude unused Serial objects and waveform/PWM code by default. External components using these features must explicitly enable them.
This is a breaking change for external components in ESPHome 2026.1.0 and later.
Background
Section titled “Background”PR #12736: Serial object exclusion
Excludes Serial/Serial1 objects when not used, saving 32-64 bytes RAM.
PR #12690: Waveform code exclusion Excludes Arduino waveform/PWM subsystem when not used, saving 596 bytes RAM and 464 bytes flash.
What’s Changing
Section titled “What’s Changing”Serial Objects
Section titled “Serial Objects”Serial and Serial1 are now excluded by default unless:
- The logger component uses that UART
- An external component explicitly enables it
- YAML configuration sets
enable_serial: true
Waveform Code
Section titled “Waveform Code”The Arduino waveform subsystem (wvfState, pwmState) is now excluded by default unless:
- The
esp8266_pwmcomponent is used - An external component explicitly requires it
Who This Affects
Section titled “Who This Affects”External components that:
- Access Arduino
SerialorSerial1directly - Use Arduino PWM functions (
analogWrite,tone) - Use waveform functions (
startWaveform,stopWaveform)
Standard YAML configurations are not affected - the logger and esp8266_pwm components automatically enable the required features.
Migration Guide
Section titled “Migration Guide”Serial Access
Section titled “Serial Access”If your external component accesses Arduino Serial directly:
# In your component's __init__.pyfrom esphome.core import COREfrom esphome.components.esp8266.const import enable_serial, enable_serial1
async def to_code(config): if CORE.is_esp8266: enable_serial() # Enable Serial (UART0) # or enable_serial1() # Enable Serial1 (UART1)Waveform/PWM Functions
Section titled “Waveform/PWM Functions”If your external component uses waveform or PWM functions:
# In your component's __init__.pyfrom esphome.core import COREfrom esphome.components.esp8266.const import require_waveform
async def to_code(config): if CORE.is_esp8266: require_waveform()YAML Override (for users)
Section titled “YAML Override (for users)”Users can force-enable Serial in YAML:
esp8266: board: esp01_1m enable_serial: true # Force-enable Serial (UART0) enable_serial1: true # Force-enable Serial1 (UART1)Functions Requiring enable_serial/enable_serial1
Section titled “Functions Requiring enable_serial/enable_serial1”// These require enable_serial() or enable_serial1():Serial.begin(...)Serial.print(...)Serial.read()Serial.available()Serial1.begin(...)Serial1.print(...)// ... any Serial or Serial1 methodFunctions Requiring require_waveform()
Section titled “Functions Requiring require_waveform()”// These require require_waveform():analogWrite(pin, value)tone(pin, frequency)noTone(pin)startWaveform(...)stopWaveform(...)Recommended Alternative
Section titled “Recommended Alternative”Instead of using Arduino Serial directly, consider using the uart component:
uart: tx_pin: GPIO1 rx_pin: GPIO3 baud_rate: 9600This provides a consistent API across all platforms (ESP8266, ESP32, RP2040, etc.).
Supporting Multiple ESPHome Versions
Section titled “Supporting Multiple ESPHome Versions”from esphome.core import CORE
async def to_code(config): if CORE.is_esp8266: try: from esphome.components.esp8266.const import enable_serial enable_serial() except ImportError: # ESPHome < 2026.1.0 - Serial always included passTimeline
Section titled “Timeline”- ESPHome 2026.1.0 (January 2026): Features excluded by default
- No deprecation period - behavior changed directly
Finding Code That Needs Updates
Section titled “Finding Code That Needs Updates”# Find Serial usage in C++grep -rn "Serial\." your_component/grep -rn "Serial1\." your_component/
# Find PWM/waveform usagegrep -rn "analogWrite" your_component/grep -rn "tone(" your_component/grep -rn "startWaveform" your_component/Compilation Errors
Section titled “Compilation Errors”If your component uses excluded features without enabling them, you’ll see linker errors:
undefined reference to `Serial'undefined reference to `Serial1'undefined reference to `startWaveform'The fix is to add the appropriate enable_* or require_* call in your Python code.
Questions?
Section titled “Questions?”If you have questions about migrating your external component, please ask in:
- ESPHome Discord - #devs channel
- ESPHome GitHub Discussions
Related Documentation
Section titled “Related Documentation”Copyright © 2026 ESPHome - A project from the Open Home Foundation
Comments
Feel free to leave a comment here to discuss this post with others. You can ask questions, share your experience, or suggest improvements. If you have a question about a specific feature or issue, please consider using the ESPHome Discord. Stick to English and follow ESPHome's code of conduct. These comments exist on a discussion on GitHub, so you can also comment there directly if you prefer.