Lit Element — Complete Guide
DodaTech
Updated 2026-06-28
2 min read
In this tutorial, you will learn about Lit Element. We cover key concepts, practical examples, and best practices to help you master this topic.
Lit is a lightweight library for building Web Components with reactive properties, declarative templates, and efficient re-rendering using lit-html.
What You'll Learn
- How to define Lit components
- How to use reactive properties
- How Lit templates update efficiently
- How to compose Lit components
Why It Matters
Vanilla Web Components require manual rendering, property Reflection, and event handling. Lit automates these patterns, making component development faster and less error-prone.
flowchart LR A[Lit Component] --> B[Reactive Properties] A --> C[Lit-html Templates] A --> D[Shadow DOM] B --> E[Auto attribute reflection] B --> F[Re-render on change] C --> G[Efficient DOM updates]
Basic Lit Component
import { LitElement, html, css } from 'lit';
class MyElement extends LitElement {
static properties = {
name: { type: String },
count: { type: Number },
active: { type: Boolean, reflect: true }
};
static styles = css`
:host { display: block; padding: 16px; }
.highlight { color: blue; }
`;
constructor() {
super();
this.name = 'World';
this.count = 0;
this.active = false;
}
render() {
return html`
<h1>Hello, ${this.name}!</h1>
<p>Count: ${this.count}</p>
<button @click=${this._increment}>+1</button>
<p class=${this.active ? 'highlight' : ''}>Status: ${this.active}</p>
`;
}
_increment() {
this.count++;
}
}
customElements.define('my-element', MyElement);
Reactive Properties
import { LitElement, html } from 'lit';
class UserCard extends LitElement {
static properties = {
userId: { type: Number },
user: { state: true }, // Internal state, not reflected
loading: { type: Boolean }
};
constructor() {
super();
this.userId = 0;
this.user = null;
this.loading = false;
}
willUpdate(changedProps) {
if (changedProps.has('userId')) {
this._fetchUser();
}
}
async _fetchUser() {
this.loading = true;
const response = await fetch(`/api/users/${this.userId}`);
this.user = await response.json();
this.loading = false;
}
render() {
if (this.loading) return html`<p>Loading...</p>`;
if (!this.user) return html`<p>No user</p>`;
return html`
<h2>${this.user.name}</h2>
<p>${this.user.email}</p>
`;
}
}
customElements.define('user-card', UserCard);
Common Mistakes
- Forgetting to import LitElement from 'lit'
- Using state: true for properties that should trigger re-render but not reflect
- Modifying arrays/objects in place (Lit needs new references)
Practice Questions
- What does reflect: true do in a property definition? Reflects the property value back to the HTML attribute.
- How does Lit detect property changes? By checking !== comparison on set.
Mini Project
Convert a vanilla Web Component to Lit. Choose a component from a previous lesson and rewrite it using Lit's reactive properties, lit-html templates, and scoped styles.
What's Next
Lesson 20: Stencil
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro