Shoelace

A forward-thinking library of professionally designed, accessible web components that work with any framework.

Library
npm
v2.20.1
13,848stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
57/100Fair
Development Activity16
Maintenance44
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture85
Code Quality82
Innovation88
Learning Curve85

Shoelace is an open-source collection of roughly 58 professionally designed, accessibility-conscious web components built with Lit. Because it’s built on native Custom Elements, Shoelace works identically in React, Vue, Angular, Svelte, or plain HTML, and it can even load straight from a CDN with no build step required.

Development on Shoelace itself has ceased in favor of its successor, Web Awesome, from the same maintainer. The existing 2.x line remains available under the MIT license and is stable for continued use, but new features and fixes now land in Web Awesome instead.

What You Get

  • 58 accessible, themeable components covering buttons, forms, overlays, navigation, and data display
  • A CSS custom-property theming system with an official light and dark theme included out of the box
  • Typed React wrapper components generated via @lit/react, plus first-class support for Vue, Angular, Svelte, and vanilla HTML
  • A CDN-ready autoloader and ES module builds so components can be dropped into a page with zero build tooling
  • Built-in localization support via a Localize controller for translating component strings

Common Use Cases

  • Building a consistent design system for a multi-framework product without rewriting components per stack
  • Adding polished form controls (input, select, checkbox, color-picker) to a legacy server-rendered app via a CDN script tag
  • Prototyping admin dashboards and internal tools quickly using pre-styled cards, tables, and dialogs

Under The Hood

Architecture Shoelace’s roughly 58 components are built on LitElement/Lit 3, each extending a shared ShoelaceElement base class (src/internal/shoelace-element.ts) that adds typed custom-event emission and localization support. Cross-cutting concerns are implemented as Lit reactive controllers rather than mixins or inheritance chains: FormControlController (src/internal/form.ts) lets any component participate in native HTML form submission and validation via a WeakMap-keyed registry of forms and controls, HasSlotController (src/internal/slot.ts) tracks slotted content, and LocalizeController (src/utilities/localize.ts) handles translated strings. Each component directory (e.g. src/components/button/) pairs a .component.ts class with a .styles.ts file and a barrel re-export, and static dependencies declarations (e.g. SlButton declaring SlIcon and SlSpinner) let the build tooling bundle only the sub-components actually referenced. A custom esbuild-based script (scripts/build.js) compiles the TypeScript sources into both ES module output for bundlers and a CDN-ready autoloader bundle.

Tech Stack The library is TypeScript (94% of the codebase) built on Lit 3.2 for the custom-element layer, @floating-ui/dom for popover/tooltip positioning, @ctrl/tinycolor for the color-picker, and @shoelace-style/localize for i18n — lightweight, purpose-specific dependencies rather than a heavy framework. The build pipeline uses esbuild directly (no webpack/Rollup config) driven by a custom Node script, with @custom-elements-manifest/analyzer generating the custom-elements.json used for IDE autocomplete and the React type wrappers via @lit/react. The documentation site is a separate Eleventy (11ty) project under docs/. Testing runs on @web/test-runner with Playwright as the browser driver, and linting/formatting are enforced via ESLint (typescript-eslint) and Prettier with lint-staged pre-commit hooks.

Code Quality Shoelace has 60 co-located *.test.ts files across its component and internal-utility directories, run through @web/test-runner against real browsers via Playwright rather than a DOM-simulation library, giving higher-fidelity coverage of focus management and custom-element lifecycle behavior. tsconfig.json enables strict, noUnusedLocals, noUnusedParameters, noImplicitReturns, and useUnknownInCatchVariables, and npm run lint runs ESLint with --max-warnings 0 — zero tolerance for lint issues in CI. Every public class, property, event, slot, and CSS part is documented with structured JSDoc tags (@event, @slot, @csspart, @since) that feed the generated custom-elements.json, keeping documentation and implementation from drifting apart. The project itself is now in sunset/maintenance-only mode — the README states there is no active development and issues/PRs are redirected to the successor project, Web Awesome — so this reflects a mature, frozen 2.x codebase rather than one under active churn.

API Design Because every component is a standard custom element, the API surface is just HTML: <sl-button variant="primary">Save</sl-button> requires no imports beyond a single script tag, and props/attributes/events follow one consistent sl- prefix and naming convention across all 58 components (e.g. every focusable component emits sl-focus/sl-blur, every validatable one emits sl-invalid). CSS parts (::part(base), ::part(label)) and CSS custom properties give consumers a documented, stable styling API instead of requiring them to reach into shadow DOM internals. The dedicated dist/react wrapper removes the usual friction of using web components from React (event binding, ref forwarding) by generating typed wrapper components via @lit/react, and the CDN autoloader means a developer can go from zero to a working component with a single <script type="module"> tag and no build step — a notably low barrier to entry compared to most component libraries.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search