Gettin stairtit wi Lily
Pick a framework, clone the monorepo an open its headless library or example app, an stairt composin yer ain pages. Prefer a guidit path? Stairt wi the tutorials.
Install
Lily lives in ae Git monorepo, wi a directory for ilka framework's headless library, helper packages an example app. The fastest wey tae try it is tae clone the monorepo an open the headless library for yer stack:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-react-headless
pnpm install
The same pattern wirks for the ither frameworks:
@lilydesignsystem/html-headless— nae install needit; copy.htmlfiles@lilydesignsystem/svelte-headless—pnpm install@lilydesignsystem/react-headless—pnpm install@lilydesignsystem/vue-headless—pnpm install@lilydesignsystem/angular-headless—pnpm install@lilydesignsystem/nunjucks-headless—pnpm installlily-design-system-blazor-headless—dotnet build
The headless libraries are designit tae be clonit or vendorit — treat the source as the source o truth an copy whit ye need. The preference helpers additionally come as installable packages wi a build an publish pipeline (npm for the JS frameworks, NuGet for Blazor).
Uise a headless component
Headless components ship semantic HTML, ARIA, an props — but nae CSS. Here's a Button in ilka framework:
HTML
<button class="button" type="button" aria-label="Save">
Save
</button>
Svelte
<script>
import Button from "lily-design-system-svelte-headless/components/Button/Button.svelte";
</script>
<Button onclick={save}>Save</Button>
React
import Button from "lily-design-system-react-headless/components/Button";
<Button onClick={save}>Save</Button>
Vue
<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>
<Button @click="save">Save</Button>
Angular
import { Button } from "@lilydesignsystem/angular-headless";
@Component({
imports: [Button],
template: `<lily-button (click)="save()">Save</lily-button>`,
})
Blazor
<Button OnClick="Save">Save</Button>
Nunjucks
{% from "components/button/macro.njk" import button %}
{{ button({ text: "Save", type: "button" }) }}
Uise a styled example
The example apps include CSS, routes, an full demo pages. The fastest wey tae experiment is tae stairt the SvelteKit, Next, Nuxt, Analog, or Eleventy example app an view the demo at /components.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-sveltekit-examples
pnpm install
pnpm run dev
Then open http://localhost:5173 an brouse /components.
Stylin an design tokens
Ilka component renders wi a single kebab-case class on its root element. For example, <Button> renders <button class="button">. Style it hooever ye like:
.button {
background: var(--my-primary);
color: #fff;
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
}
.button:hover { background: var(--my-primary-hover); }
The defauld Lily colour palette (uised in the example apps) is:
- Primary:
#2563eb - Danger:
#dc2626 - Warnin:
#f59e0b - Success:
#16a34a - Page backgrund:
#f9fafb - Caird backgrund:
#ffffff
Thir are suggestions, no requirements. Replace them wi yer ain brand palette an Lily comes alang happily.
Ready-made themes
Dinnae want tae write CSS frae scart? Lily ships 57 standalane reference themes in the themes/ directory. Ilkane is ae stylesheet targetin the Lily class hooks — link it an ye're styled:
<link rel="stylesheet" href="/assets/themes/united-kingdom-government-digital-service.css" />
The set covers:
- Public sector — NHS England, NHS Scotland, an NHS Wales (patient-facin an practitioner-facin variants ilkane), GOV.UK GDS, an the U.S. Web Design System.
- Vendor-inspired — Adobe Spectrum, Mozilla Protocol.
- General purpose — light, dark, nord, dracula, wireframe, an thirty-odd mair.
Theme selectors uise :where(...), sae yer ain CSS aye wins on specificity. Pair them wi the theme-picker helper ablow for runtime switchin, or follae the
theming tutorial.
Preference helpers
Ilka framework haes aicht wee pickers, ilkane its ain
lily-design-system-{framework}-{package} package (an a picker-bar that assembles them). Ilkane is a headless icon-button that opens a popup — a listbox, a list o links, a seek form, or (for date-time-picker) a date-picker dialog — no a native
<select>; is SSR-safe; an ships nae CSS:
-
theme-picker — loads theme stylesheets at runtime bi swappin a managed
<link>, setsdata-themeon the document, an optionally persists taelocalStorage. -
locale-picker — sets
langandir(wi automatic RTL detection) sae yer i18n library can follae; it performs nae translation itsel. -
text-size-picker — sets
data-text-sizeon the document; yer CSS maps ilka value tae font sizin. -
motion-picker — sets
data-motionon the document, stairtin frae the visitor's reduced-motion settin; yer CSS an scripts decide whit tae suppress. - search-picker — an icon button that opens a seek field; submittin navigates tae a seek page. Owns an action, no a preference.
- link-picker — a hame icon that opens a menu o the page links yer app defines (Hame, Aboot Us, Contact Us, Privacy Policy, …). Owns an action, no a preference.
- share-picker — opens the native share sheet or a consumer-supplied destination list, plus copy-the-URL. Owns an action, no a preference: applies naething, persists naething.
-
date-time-picker — a text field plus an APG date-picker dialog for a date, a time, or baith. Owns a form value, no a preference: the ISO string round-trips tae
<input type="date">.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-theme-picker
The Svelte catalog is the canonical reference; React, Vue, Angular, HTML, Nunjucks, Web Components, an Blazor ports match it contract-for-contract. See the helpers tutorial.
Accessibility
Components target WCAG 2.2 AAA. They follae thir patterns:
- Semantic HTML elements ower generic
<div>s. <label for="id">linkin labels tae inputs.aria-labelledby/aria-describedbyfor cross-references.aria-invalid+aria-errormessagefor error states.role="alert"anaria-livefor dynamic content.aria-pressed,aria-expanded,aria-currentfor state.- Roving
tabindexfor grids.
Focus indicators are deliberately consumer-supplied — Lily never paints a defauld focus ring that clashes wi yer design. The example apps haud a clean axe-core baseline athort their routes.
Internationalization
Ilka label, placeholder, error message, an button text is a prop. There are nae hardcodit strings. Drap in yer translation framework o choice — Paraglide, i18next, vue-i18n, react-intl, .resx files, onything.
For dates, numbers, an currencies, the components accept pre-formattit strings: ye format wi Intl.DateTimeFormat /
Intl.NumberFormat / yer preferred library an pass the result.
The locale-picker helper signals the chosen locale tae yer i18n library bi settin lang an dir on the document root.
Testin
Ilka framework subproject ships its ain tests uisin its idiomatic stack:
- HTML: WebDriverIO rinnin real browsers.
- Svelte: Vitest +
@testing-library/svelte. - React: Vitest +
@testing-library/react. - Vue: Vitest +
@testing-library/vue. - Angular: Vitest + TestBed (through the Analog Vite plugin).
- Nunjucks: Vitest wi a render helper.
- Blazor: bUnit.
Tests uise Vitest's biggit-in matchers anely — never
jest-dom matchers. This keeps the test suites portable. The example apps add Playwright end-tae-end suites, axe-core accessibility baselines, an a responsive viewport sweep.
AI agents
This site publishes llms.txt an llms.json at its root — a curatit map o its maist important pages, for onie tool that follaes the llms.txt convention.
The canonical monorepo additionally ships twa
Claude Skills:
lily-design-system-skill, a general-purpose skill coverin Lily's concepts, terminology, an composition patterns for onybody biggin wi the system, an lily-design-system-maintainer-skill, a technical skill coverin the monorepo's required-files layoot an tooling for onybody wirkin on it. Baith live at the root o the
canonical monorepo.
Troubleshootin
A component renders but looks unstyled
That's headless wirkin as intendit — nae CSS ships wi the component. Either write CSS against the component's kebab-case class (shawn on ilka catalog page) or link ane o the 57 ready-made themes.
My CSS disnae seem tae apply ower a theme
It shuid — theme selectors are wrapped in :where(...), which haes zero specificity. If a rule still loses, check that yer stylesheet loads efter the theme's <link> an that the selector actually matches the component's class hook.
pnpm install fails wi a peer or version error
Uise a current pnpm (v10+) an Node 22+. Ilka subproject pins its framework versions in its ain package.json; if yer global toolchain is aulder, pnpm env use --global lts is the quickest fix.
Screen reader announces the wrang name for a control
Check the component's required label prop — components that lack visible text require ane, an consumer-supplied
aria-label / aria-labelledby passed through rest-props intentionally win ower the biggit-in wirin. Ilka catalog page documents the component's ARIA contract.
The theme-picker helper disnae switch stylesheets
Confirm themesUrl points at a directory the browser can fetch (serve the themes/ files as static assets) an that the theme slugs in yer themes prop match the file names. The helper swaps the href o ae managed
<link data-lily-theme-picker> — inspect it in devtools tae see the URL bein requestit.
Something else is broken
Open an issue wi a minimal reproduction at github.com/LilyDesignSystem/lily-design-system — or see community an support.
Contributin
Lily is young an walcomes collaboration. The maist uiseful contributions richt noo are:
- New components (especially patterns frae established design systems).
- New themes — ilkane is ae standalane stylesheet, a weel-scopit first PR.
- Better example stylin — shaw whit's possible.
- Translations o example app strings.
- Bug reports wi minimal reproduction.
- Accessibility audits wi screen readers an assistive tech.
Open issues an PRs at github.com/LilyDesignSystem/lily-design-system.
Community an support
- Questions an bug reports — open an issue at github.com/LilyDesignSystem/lily-design-system.
- Email — the maintainer reads joel@joelparkerhenderson.com an walcomes collaboration, guidance, an feedback.
- Mirrors — Lily is an aa pushed tae Codeberg an GitLab, sae ye can participate frae the forge ye prefer.
- Conduct — the project follaes a standard code o conduct; be kind, assume guid faith.
FAQ
Why headless insteid o styled?
Pre-styled components are convenient — until they dinnae match yer brand. Headless components are slightly mair wirk up front but gie ye total control o the visual design. The example apps an the 57 themes shaw weys tae style them; ye can tak thae or replace them entirely. The langer argument is on Why Lily.
Why sae mony components?
Lily aims tae cover the patterns maist apps need wioot forcin ye tae big them frae scart — includin deep cuts like national identifier inputs an editorial scrollytelling. The catalog draws frae a dizzen established design systems plus original wirk — see Aboot.
Can I uise Lily wi Tailwind?
Aye. Ilka component exposes a single kebab-case root class plus a consumer-provided className / class. Layer Tailwind utilities on tap hooever ye like.
Can I uise Lily wi semantic CSS frameworks like DaisyUI?
Aye. The kebab-case class names on the root element wirk as semantic CSS hooks. Pair Lily wi a semantic framework an ye git pre-styled components that still respect ARIA an i18n.
Is there an npm package?
The preference helpers ship as packages wi an npm/NuGet publish pipeline. The headless component libraries are designit tae be clonit or vendorit — the source is the deliverable, sae ye can read, trim, an ain exactly whit ye ship. Registry publishin for the headless libraries remains on the roadmap.
Why multi-licenced?
Different projects hae different licence needs. BSD an MIT are permissive, Apache-2.0 haes a patent grant, an the GPL options support copyleft. Choose whichever fits yer situation.
Hoo dae I report a bug or request a feature?
Open an issue on the GitHub repository, or email joel@joelparkerhenderson.com.