| Crates.io | esphome-native-api |
| lib.rs | esphome-native-api |
| version | 2.0.6 |
| created_at | 2025-04-26 22:58:09.569413+00 |
| updated_at | 2026-01-17 00:13:06.134719+00 |
| description | Rust implementation of the ESPHome native API for communication with ESPHome devices, supporting both encrypted and plaintext connections. |
| homepage | https://github.com/UbiHome/esphome-native-api |
| repository | https://github.com/UbiHome/esphome-native-api |
| max_upload_size | |
| id | 1650658 |
| size | 6,176,383 |
Documentation | GitHub | Crate | docs.rs
Implementation of the esphome native api for Rust.
This is still work in progress, so the API surface may change. But it is already quite usable. Just try the examples. The implementation is already used by UbiHome to make OS based devices available to Home Assistant.
Full support for ESPHome native API protocol, including encryption. The crate can be used for Server and Client implementations.
Support for multiple ESPHome versions via feature flags (not yet implemented)
cargo add esphome_native_api
Look at the examples folder for reference implementations, e.g. encrypted_server.rs.
Version Compatibility
This crate only supports one ESPHome protocol version (marked by the default feature flag).
If you only need the Proto Messages you can install the crate with the feature flags enabled for the version you plan to use. Example:
[dependencies] esphome-native-api = { version = "0.0.0", features = ["version_2025_12_1"] }
use esphome_native_api::esphomeapi::EspHomeApi;
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to an ESPHome device
let stream = TcpStream::connect("192.168.1.100:6053").await?;
// Create API instance
let mut api = EspHomeApi::builder()
.name("my-client".to_string())
.build();
// Start communication
let (tx, mut rx) = api.start(stream).await?;
// Process messages
while let Ok(message) = rx.recv().await {
println!("Received: {:?}", message);
}
Ok(())
}
The EspHomeServer provides a higher-level abstraction that manages entity keys internally (work in progress):
use esphome_native_api::esphomeserver::EspHomeServer;
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let stream = TcpStream::connect("192.168.1.100:6053").await?;
let mut server = EspHomeServer::builder()
.name("my-server".to_string())
.build();
let (tx, mut rx) = server.start(stream).await?;
// Handle incoming messages
while let Ok(message) = rx.recv().await {
// Process message
}
Ok(())
}
While reverse engineering the "missing" documentation of the API was reconstructed: https://ubihome.github.io/esphome-native-api/native_api/