Lit has first-class TypeScript support, and most real-world Lit projects are written in TypeScript. This lesson gives an overview before the dedicated lessons on decorators, typed properties, and typed events.
Why TypeScript Is the Recommended Default
Lit's own source code is written in TypeScript, and its decorators (@customElement, @property, @state, and others) are specifically designed with TypeScript's type system in mind — property types, event detail shapes, and controller interfaces all benefit from real compile-time checking rather than relying purely on runtime behavior or documentation.
You can absolutely use Lit with plain JavaScript (as many of the earlier lessons in this course have shown), and it works well. But once a project grows past a handful of components, TypeScript's autocomplete and type checking for properties, events, and template values noticeably reduces an entire class of bugs — mistyped property names, wrong event detail shapes — before you even run the code.
experimentalDecorators: true is required for @customElement, @property, and other Lit decorators to compile.
useDefineForClassFields: false avoids a subtle bug where class field initialization can override Lit's own generated accessors.
strict: true is recommended (not required) — it catches many property-typing mistakes that would otherwise only surface at runtime.
Lit ships its own .d.ts type declarations, so no separate @types/lit package is needed.
Lit + TypeScript Quick Reference
Key facts for setting up a TypeScript-based Lit project.
Item
Detail
Decorators import
import { customElement, property, state } from 'lit/decorators.js';
Required tsconfig flag
experimentalDecorators: true
Recommended tsconfig flag
useDefineForClassFields: false
Type declarations
Included with the lit package — no separate @types needed
JS alternative
Plain static properties object, fully supported, no decorators required
Decorators vs. Plain TypeScript Without Decorators
It's entirely possible to write Lit components in TypeScript without using decorators at all, relying on the plain static properties object with type annotations on the class fields themselves. Most teams prefer decorators for their conciseness, but the plain approach remains fully valid and sometimes preferred by teams avoiding experimental TypeScript features.
class UserCard extends LitElement {
static properties = { name: { type: String } };
declare name: string; // type annotation without a decorator
render() {
return html`<p>${this.name}</p>`;
}
}
declare tells TypeScript this field's type without generating its own initializer, since static properties already handles the runtime behavior.
How Much Type Checking Templates Actually Get
It's worth setting accurate expectations: the *inside* of an html`...` template literal is still just a string as far as TypeScript's type checker is concerned — TypeScript checks the JavaScript *expressions* inside ${...} normally, but it doesn't validate the surrounding HTML markup itself (unlike, say, JSX in React, which TypeScript understands structurally). Editor tooling (the Lit VS Code plugin) adds HTML-aware syntax highlighting and some validation on top, but this isn't the TypeScript compiler itself.
Common Mistakes
Forgetting experimentalDecorators: true, causing a compile error the moment @customElement or @property is used.
Leaving useDefineForClassFields at its default in a decorator-based project, silently breaking reactive property behavior.
Expecting TypeScript to catch invalid HTML markup inside an html`...` template — it only checks the JavaScript expressions inside ${...}.
Installing an unnecessary @types/lit package — Lit already ships its own accurate type declarations.
Key Takeaways
Lit has first-class TypeScript support, and decorators are the most common, recommended way to write Lit + TypeScript components.
experimentalDecorators: true and useDefineForClassFields: false are the two settings most Lit + TypeScript projects need.
Plain static properties with type annotations remains a fully valid, decorator-free alternative.
TypeScript checks expressions inside ${...}, not the surrounding HTML markup itself.
Pro Tip
Install the official Lit VS Code (or equivalent editor) plugin alongside your TypeScript setup — it adds HTML syntax highlighting and some template-level validation inside html`...` literals that the TypeScript compiler alone doesn't provide.
You now have an overview of Lit and TypeScript together. Next, go deep on the decorators Lit provides.