Custom element callbacks
connectedCallback()
Called when the element is added to the document. Lit uses this to set up the shadow root (on first connection) and enable the update cycle.
super.connectedCallback(). Lit’s implementation creates the renderRoot and calls hostConnected() on any registered reactive controllers.
disconnectedCallback()
Called when the element is removed from the document. Use it to remove external event listeners, cancel timers, and release any resources held by the component.
attributeChangedCallback()
Called by the browser when one of the element’s observed attributes changes. Lit implements this to synchronize attribute values with reactive properties:
@property() options instead and let Lit handle the conversion.
The reactive update cycle
When a reactive property changes, Lit runs the following sequence asynchronously:willUpdate through updated is synchronous once it starts. Only the scheduling is asynchronous.
requestUpdate()
Called automatically when a reactive property changes. You can also call it manually to trigger an update from non-property state:
requestUpdate() before the microtask queue drains are coalesced into a single update.
scheduleUpdate()
Controls the timing of the update. By default it calls performUpdate() synchronously in a microtask. Override to defer updates to a specific frame:
performUpdate()
Executes the update synchronously. Can be called directly to flush a pending update immediately (useful in tests):
shouldUpdate(changedProperties)
Return false to abort the update cycle. Rarely needed — prefer willUpdate for conditional computation.
willUpdate(changedProperties)
Called before update() and render(). Use it to compute derived values that depend on other properties:
willUpdate runs before controllers’ hostUpdate() hooks and before render(), so derived values computed here are available in the template.
update(changedProperties)
Reflects property values to attributes and (in LitElement) calls render(). You can override this, but you must call super.update(changedProperties) to perform rendering:
Setting reactive properties inside
update() does not trigger another synchronous update — it schedules the next update instead.render()
Defined by LitElement. Return a TemplateResult describing the component’s shadow DOM:
noChange, meaning no DOM is rendered. Always override render() in your component.
Setting reactive properties inside render() does not trigger another update.
firstUpdated(changedProperties)
Called once, after the first update completes and the component’s DOM is available. Use it for one-time setup that requires access to rendered DOM:
hasUpdated is false before this call and true after.
updated(changedProperties)
Called after every update, including the first. Use it to react to DOM changes, e.g. to observe a property change and perform a side effect:
updateComplete
updateComplete is a Promise<boolean> that resolves when the current update cycle (and any update triggered during it) completes:
true if the component completed without triggering another update, or false if a property was set during updated().
To extend updateComplete to include additional async work (e.g., waiting for a child element), override getUpdateComplete():
hasUpdated
A boolean property that is false before the first update and true after firstUpdated() has been called:
Lifecycle at a glance
connectedCallback
Element added to the DOM. Shadow root created on first connection. Update cycle enabled.
requestUpdate
Property change or manual call schedules an async update. Multiple changes are batched.
update(changedProperties) → render()
Reflect attributes and call
render(). Lit applies the returned TemplateResult to the shadow root.updated(changedProperties)
Called after every render. Use for side effects driven by property changes.
updateComplete resolves
The
updateComplete promise resolves. Awaiting it gives you a point after which the DOM reflects the latest state.