Compared to alternatives
Choose between the ways to get hot reloading for Lit, by what each keeps across an edit and what it asks of your code. The facts about other tools come from their own documentation, as of October 2026; follow the links for the current state.
At a glance
Section titled “At a glance”| Lit DevTools | Plain Vite | Open WC HMR | Gracile HMR | |
|---|---|---|---|---|
| Dev server | Vite 7 and 8 | Vite | Web Dev Server only | Vite |
| On a component edit | Patches the class in place | Reloads the page | Updates the class in place | Updates templates and styles without a reload |
| Changes to your base class | None | None | Needs a hotReplacedCallback |
Lit preset |
| Element state | Kept | Lost | Kept | Not stated |
| Unchanged sibling DOM | Kept, through template interning | Rebuilt by the reload | Not stated | Not stated |
| State of re-created child elements | Transferred by default | Lost | Not stated | Not stated |
| On a CSS file edit | Swaps the shared sheet’s text, no re-render | Reloads the page | Not stated | Updates styles without a reload |
| DevTools panel and MCP tools | Yes | No | Not in scope | Not in scope |
| Component docs from JSDoc and Custom Elements Manifests | In the panel, Lit Inspector and over MCP | No | Not in scope | Not in scope |
| Status | Pre-1.0, released often | Stable | Marked experimental | Only the core and Lit preset are tested |
Plain Vite
Section titled “Plain Vite”Vite reloads the page when an edited module has no hot-update handler, and a Lit component module has none. The reload is reliable and needs nothing from you, but every element starts over. The Why page shows the difference side by side.
Open Web Components’ HMR plugin
Section titled “Open Web Components’ HMR plugin”@open-wc/dev-server-hmr patches custom element classes in place for
Web Dev Server. Its documentation marks it experimental and says it works only
there, not in Vite. Your base class implements a hotReplacedCallback that
the plugin calls after a patch; it ships presets that do this for Lit 2 and 3.
Its documented limits: constructors do not re-run for existing elements, new
fields are not available on them, and a changed observedAttributes list
needs a refresh.
Gracile’s HMR plugin
Section titled “Gracile’s HMR plugin”@gracile-labs/hmr brings the same approach to Vite. It derives
from vite-plugin-web-components-hmr, itself a fork of the Open Web
Components plugin, and has a preset for Lit. Its documentation states that only
the core and the Lit preset are tested.
Lit DevTools
Section titled “Lit DevTools”The plugin targets Lit on Vite and goes further than swapping the class:
- It patches the class the browser registered first, so nothing in your component code changes and no base-class hook is needed.
- It interns templates, so an edit to one
htmlliteral rebuilds only that literal’s DOM. Siblings keep focus, selection and scroll. - It carries state onto child elements an edited template re-creates.
- It adds what a Lit project needs around HMR: shared stylesheets, a source overlay, and a DevTools panel your coding agent can read, which shows each component’s docs from its JSDoc or a Custom Elements Manifest.
It shares one limit with the others: a changed observedAttributes list
cannot be applied in place. The limitations page
lists the rest.