Skip to content

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.

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

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-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-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.

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 html literal 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.