NV Elements Catalog Starters Repo System Themes About Getting Started Changelog Metrics Support Accessibility Contributions Requests Migration Deprecations Integrations Installation MCP CLI Lint Angular Bundles Extensions Go Hugo Import Maps Lit NextJS Nuxt Preact React SolidJS Svelte TypeScript Vue Foundations Typography Iconography Themes Design Tokens Size & Space Objects Interactions Support Status Color Animation Fonts Layers Custom Layout Horizontal Vertical Grid Popovers i18n Visualization View Transitions Elements Accordion Alert Avatar Badge Breadcrumb Button Button Group Card Chat Message Checkbox Color Combobox Copy Button Datagrid Integrations Column Action Column Alignment Column Fixed Column width Container Card Display Settings Footer Heatmap Keynav Multi Select Pagination Panel Detail Panel Grid Performance Placeholder Row Action Row Groups Row Sort Scroll Height Single Select Stripe Date Datetime Dialog Divider Dot Drawer Dropdown Dropdown Group Dropzone File Forms Validation Actions Control Icon Icon Button Input Input Group Logo Menu Month Notification Page Page Header Page Loader Pagination Panel Progressive Filter Chip Progress Bar Progress Ring Password Preferences Input Pulse Radio Range Resize Handle Search Select Skeleton Sort Button Sparkline Star Rating Steps Switch Tabs Tag Textarea Time Toast Toggletip Toolbar Tooltip Tree Week Patterns Authentication Browse Dashboard Editor Empty States Heatmap Keyboard Shortcut Logging Media Onboarding Panel Responsive Search Subheader Trend Code Codeblock Monaco Input Diff Input Editor Diff Editor Problems Markdown Markdown CSS Utility Labs Responsive Layout Viewport Container Patterns Forms API Design Properties & Attributes Slots Registration CustomEvents Stateless Composition Styles Packaging Glossary Logs Internal Guidelines Agent Harness Documentation Examples TypeScript Testing Unit Testing Accessibility Testing Lighthouse Testing SSR Testing Visual Testing Troubleshooting Component Creation Internal Examples All Examples

Properties & Attributes

Properties/attributes represent an element's visual state. Examples:

  • types status: error | success | warning
  • states expanded | selected | disabled
  • behaviors closable | draggable

    

Properties (@property) in Lit enable setting the property on the element via JavaScript or HTML Attributes.


    
🎓

Learn: by default when you set a property, Lit does not update the corresponding attribute in the DOM for performance. If the attribute serves as a style hook example, :host([disabled]) then you can add the reflect option to the property decorator.

Impossible states

Properties/Attributes should avoid enabling “impossible states”. Conflicting APIs on a single element cause impossible states.

Do Don't

    

    

🎓 Learn: make impossible states impossible

Boolean Types

Boolean property/attribute type behave the same as native HTML element boolean types. The presence of the attribute is truthy and absence of the attribute is falsy. (MDN Reference)


    
Warning: avoid double negations on attributes as this breaks the default expectations of native HTML elements, examples (disable-closable, not-closable, closable=”false”) Warning: supporting React requires a custom coercion function that sets boolean attributes to a value of “false” example React issue.

Primitive Types

Note: primitive type guidance is for atomic and highly reusable element libraries

While Lit keeps both properties and attributes in sync, do not use complex types like object and array on the API. Since HTML cannot represent JavaScript objects, Lit must JSON parse attributes and reflect them anytime there is a change to ensure the JavaScript property and HTML attribute are in sync. This can be expensive to parse when using an object or array and cause unexpected behaviors such as lost object references for the user.

Use string | number | boolean Avoid object | array

Complex types cause compatibility and usability issues as it can require the developer to use JavaScript to render content. This can make it difficult for user-generated content like CMS systems or SSR (Server Side Rendering) to easily render static HTML.

Warning: avoid using @property on built in properties/attributes on the HTMLElement as the decorator overrides the getter/setter and can cause unexpected behavior. read more

🎓 Learn about Web Fundamentals Attributes vs Properties.

Data Elements

Some components exist as a representational view of a pure data structure that cannot be meaningfully distilled into primitive attributes or expressed declaratively as HTML child elements. In these cases a complex type property is acceptable.

A component qualifies as a Data Element when all the following are true:

  1. The component renders a data structure (arrays, series, matrices) rather than composable UI content.
  2. The data is not representable using a reasonable number of primitive attributes or slotted children.
  3. The component is a leaf node -- it does not compose other application-level elements.

    

Components that meet this criteria should implement the DataElement interface so the pattern is consistent and discoverable across the library.


    

The data property should use Lit's @property decorator without the reflect option to avoid serializing large structures back to the DOM attribute.


    
Do Don't

    

    

Warning: only use DataElement for data structures that have no reasonable declarative HTML representation. If primitive attributes, slots, or child elements can represent the content, prefer those approaches.