Getting Started with Espalier
Espalier is a framework-agnostic web component library distributed as standard ES modules. Because every Espalier element is a native custom element, it works in any framework — or no framework at all.
This guide walks you through installation, initial setup, and your first component.
Installation
Install the package from npm:
npm install @taprootio/espalier
@taprootio/espalier is published on the public npm registry, so installation
does not require scoped registry configuration or a GitHub authentication token.
Peer Requirements
Espalier ships with zero runtime npm dependencies and requires Lit as a peer dependency. If your project already uses Lit, the existing installation will be shared automatically through npm's dependency resolution; otherwise install Lit alongside Espalier.
Browser Support
Espalier requires Chrome/Edge 120+, Firefox 128+, or Safari 18+. If your deployment has a managed browser policy, check the Browser Support page for the full requirements matrix and required polyfills before proceeding.
Setting Up the Root
Every Espalier application starts with <esp-root>. This element is the orchestrator — it generates the CSS custom property cascade that every child component inherits for color, typography, and spacing.
Place it as high in the DOM as possible, typically wrapping your entire application:
<esp-root>
<!-- Your application content goes here -->
</esp-root>
<esp-root> accepts light-theme and dark-theme attributes, each of which holds a Base64-encoded partial theme object. Use the scheme attribute to choose which resolved theme is active:
<esp-root
scheme="light"
light-theme="eyJzZWVkQ29sb3IiOiJva2xjaCgwLjcgMC4xNSAyODUpIn0=">
<!-- themed content -->
</esp-root>
You can provide either scheme override, both, or neither. Omitted fields inherit from Espalier's built-in defaults. See the Theming guide for the full theme model.
Components with an icon attribute resolve icon names against the SVG sprite
configured on <esp-root>. The default is /assets/icons.svg; set
icon-sprite-url when your site deploys under a subpath, uses a CDN, or emits
hashed asset filenames:
<esp-root icon-sprite-url="/dist/icons.abc123.svg">
<esp-button label="Save" icon="save"></esp-button>
</esp-root>
Using Components
Import the components you need. Each import registers the corresponding custom element on the global registry:
import "@taprootio/espalier/root";
import "@taprootio/espalier/box";
import "@taprootio/espalier/button";
import "@taprootio/espalier/form";
import "@taprootio/espalier/form-item";
import "@taprootio/espalier/input";
import "@taprootio/espalier/pickers/pick-one";
import "@taprootio/espalier/pickers/item";
Or import everything at once:
import "@taprootio/espalier";
Once imported, use the elements directly in HTML:
<esp-button label="Save"></esp-button>
Building a Simple Form
Espalier form components participate in the browser's native form lifecycle through ElementInternals. Wrap fields in <esp-form> and <esp-form-item> to get labels, validation, and layout for free:
<esp-form>
<esp-box>
<esp-form-item label="First name" field-name="firstName">
<esp-input required></esp-input>
</esp-form-item>
<esp-form-item label="Email" field-name="email">
<esp-input input-type="email" required></esp-input>
</esp-form-item>
<esp-form-item label="Country" field-name="country">
<esp-pick-one required placeholder="Choose a country">
<esp-picker-item text="United States" value="us"></esp-picker-item>
<esp-picker-item text="Canada" value="ca"></esp-picker-item>
<esp-picker-item text="United Kingdom" value="gb"></esp-picker-item>
</esp-pick-one>
</esp-form-item>
<esp-button label="Submit" button-type="submit"></esp-button>
</esp-box>
</esp-form>
Without any extra flags, <esp-form> behaves like a native form submission. If you add use-fetch, Espalier intercepts the submit and dispatches esp-form-submit, esp-form-submit-response, and esp-form-submit-error events around the request lifecycle.
Page Layout
For full-page applications, use <esp-page> inside <esp-root> to establish the document structure with a header, navigation, and content area:
<esp-root>
<esp-page>
<esp-header slot="header">
<a slot="brand" href="/">My Application</a>
</esp-header>
<esp-menu slot="sidebar" mode="vertical">
<esp-menu-item label="Dashboard" url="/"></esp-menu-item>
</esp-menu>
<main>
<!-- page content -->
</main>
</esp-page>
</esp-root>
Browser Polyfills
Espalier is built to browser standards. Where a standard is emerging but not yet universally available, the consuming application is responsible for loading the polyfill. This keeps the library dependency-free and ensures that polyfills are dropped the moment browser support lands — without waiting for a library update.
See Browser Support for the minimum version matrix and required polyfills, or the Caveats guide for detailed per-feature rationale.
Next Steps
- Build a Site — The end-to-end path from a brand book to a themed page: anchors, roles, the lightness ramp, zones, and the shipped page shell (header, footer, scheme toggle included).
- Page Anatomy — Which component owns which region of a website. Read before building a header, footer, or reading column by hand — they ship.
- Browser Support — Minimum browser versions, required polyfills, and support policy.
- Caveats — Detailed per-feature compatibility rationale and known limitations.
- Color System — How Espalier uses OKLCH and APCA for perceptually accurate, accessible color.
- Typography — Fluid type scales and modular spacing.
- Layout — Grid, Flexbox, and Container Query patterns.
- Working with Forms — Deep dive into form participation, validation, and data collection.
- SVG Icons — How to create and reference icon sprite sheets.
- Documentation — How Espalier's docs are generated from source code.