🚀 Introducing ESPCompose – A React/TypeScript-inspired UI toolkit for ESPHome

Hi all :wave:

I’ve been working on a new open-source project called ESPCompose, and I’d love to get feedback from this community early on.


:bulb: What problem is this solving?

If you’ve worked with ESPHome + LVGL, you’ve probably felt some of this:

  • UI definitions can get verbose and hard to maintain
  • Binding data to widgets (especially dynamic Home Assistant entities) feels clunky
  • Iterating on UI often requires flash → test → repeat
  • Tooling is much more limited than what many of us are used to in modern frontend development

:brain: What is ESPCompose?

ESPCompose is a toolkit for building ESPHome UIs using a TypeScript + TSX (React-like) authoring model.

Instead of writing large, YAML-heavy UI definitions, the goal is to let you write something more declarative and composable, like this:

<Label text={() => `${temperatureSensor.state}°`} />
<Button onClick={() => light.toggle()} />

Under the hood, this is compiled into ESPHome-compatible output.


:gear: Key ideas behind the project

  • React/TypeScript-inspired authoring

    • Build UI using familiar TSX-style patterns
    • Compose reusable pieces instead of repeating blocks of YAML
  • Better data binding

    • Make it easier to connect UI widgets to changing state and Home Assistant entities
  • Reactive concepts under the hood

    • Inspired by modern reactive UI systems
    • The intent is to make dynamic UI behavior easier to express
  • Modern developer tooling

    • TypeScript-based workflows
    • Stronger editor support and better opportunities for code completion and validation
  • Improved UI development experience

    • Long term, I’d like to improve the iteration loop for UI work and reduce the pain of repeatedly flashing firmware just to test small changes

:test_tube: Current status

This project is still early and not fully done yet, but it has reached the point where I think it’s worth sharing.

Some areas are still actively being worked on:

  • LVGL widget coverage
  • Schema and metadata generation
  • Tooling and docs
  • Better development and preview workflows

:thinking: Why I’m posting now

I’d really like feedback before the project gets too far along.

I’m interested in hearing things like:

  • Does this direction sound useful?
  • What are your biggest pain points with ESPHome UI development today?
  • Would you use something like this?
  • Does the TypeScript/TSX approach feel appealing, or does it feel like unnecessary complexity?
  • What would make a project like this worth trying?

:handshake: What I’m looking for

At this stage I’m mainly looking for:

  • Feedback on the overall direction
  • Interest from potential users
  • Suggestions for features or priorities
  • Contributions from anyone interested in ESPHome, LVGL, TypeScript, tooling, or docs

:link: Project links


:pray: Final thoughts

My goal is not to replace ESPHome, but to improve the developer experience for people building more advanced, UI-driven ESPHome devices.

If this sounds interesting, I’d really appreciate your thoughts, criticism, ideas, or contributions.

1 Like

Your project is very ambitious, and I’m looking forward to your upcoming posts.

You are addressing a topic that has also been on my mind a lot recently.

Many of my goals are similar to yours:

  • UI definitions quickly become verbose and hard to maintain.

  • Binding data to widgets (especially dynamic Home Assistant entities) often feels clunky.

  • UI iteration frequently requires a flash → test → repeat cycle.

  • Tooling is still much more limited than what many of us are used to in modern frontend development.

However, my focus is not on LVGL-based rendering, but on HTML.

The foundation is a web-based file-server approach that supports uploading and downloading application files.

I use AlpineJS as the reactive framework, stored on the controller, so there are no external dependencies.

Right now, I’m working on an ESPHome application for the Indevolt SolidFlex balcony power system with LiFePO batteries.

Once all data sources are connected, UI changes no longer require recompiling controller code. You only need to upload the modified web pages.

Here is a short GIF animation of the UI.

ui-flow

Interesting. To make sure I’m following, you are showing an html page in a widget on the esphome device?

The ESPHome controller serves the HTML page, but it’s rendered client-side in the browser using Alpine.js.

For anyone following along, I’ve got a demo repo setup (GitHub - espcompose/espcompose-demo: Provides a demo example project for ESPCompose · GitHub) and some initial docs (espcompose.io).