Getting started with Lily

Pick framework, clone di monorepo and open im headless library or example app, and start to compose your own pages. You prefer guided path? Start with di tutorials.

Install

Lily dey live inside one Git monorepo, with directory for each framework headless library, helper packages and example app. Di fastest way to try am na to clone di monorepo and open di headless library for your stack:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-react-headless
pnpm install

Di same pattern dey work for di other frameworks:

  • @lilydesignsystem/html-headless — no install needed; copy .html files
  • @lilydesignsystem/svelte-headless — pnpm install
  • @lilydesignsystem/react-headless — pnpm install
  • @lilydesignsystem/vue-headless — pnpm install
  • @lilydesignsystem/angular-headless — pnpm install
  • @lilydesignsystem/nunjucks-headless — pnpm install
  • lily-design-system-blazor-headless — dotnet build

Di headless libraries dem design am to clone or vendor — treat di source as di source of truth and copy wetin you need. Di preference helpers come additionally as installable packages with build and publish pipeline (npm for di JS frameworks, NuGet for Blazor).

Use headless component

Headless components ship semantic HTML, ARIA, and props — but no CSS. Dis na Button for each 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" }) }}

Use styled example

Di example apps include CSS, routes, and full demo pages. Di fastest way to experiment na to start di SvelteKit, Next, Nuxt, Analog, or Eleventy example app and view di demo for /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 and browse /components.

Styling and design tokens

Each component dey render with one kebab-case class for im root element. For example, <Button> renders <button class="button">. Style am how you like:

.button {
  background: var(--my-primary);
  color: #fff;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
}
.button:hover { background: var(--my-primary-hover); }

Di default Lily color palette (wey dem use for di example apps) na:

  • Primary: #2563eb
  • Danger: #dc2626
  • Warning: #f59e0b
  • Success: #16a34a
  • Page background: #f9fafb
  • Card background: #ffffff

Dem be suggestions, no be requirements. Replace dem with your own brand palette and Lily go follow happily.

Ready-made themes

You no wan write CSS from scratch? Lily ship 57 standalone reference themes for di themes/ directory. Each one na one stylesheet wey target di Lily class hooks — link am and you don dey styled:

<link rel="stylesheet" href="/assets/themes/united-kingdom-government-digital-service.css" />

Di set cover:

  • Public sector — NHS England, NHS Scotland, and NHS Wales (patient-facing and practitioner-facing variants each), GOV.UK GDS, and di U.S. Web Design System.
  • Vendor-inspired — Adobe Spectrum, Mozilla Protocol.
  • General purpose — light, dark, nord, dracula, wireframe, and thirty-odd more.

Theme selectors dey use :where(...), so your own CSS go always win for specificity. Pair dem with di theme-picker helper below for runtime switching, or follow di theming tutorial.

Preference helpers

Each framework get eight small pickers, each one inside im own lily-design-system-{framework}-{package} package (and picker-bar wey put dem together). Each one na headless icon-button wey open popup — listbox, list of links, search form, or (for date-time-picker) date-picker dialog — no be native <select>; e dey SSR-safe; and e ship without CSS:

  • theme-picker — e dey load theme stylesheets for runtime by swapping managed <link>, e set data-theme for di document, and optionally e persist to localStorage.
  • locale-picker — e set lang and dir (with automatic RTL detection) so your i18n library fit follow; e no dey translate by itself.
  • text-size-picker — e set data-text-size for di document; your CSS dey map each value to font sizing.
  • motion-picker — e set data-motion for di document, wey start from di visitor reduced-motion setting; your CSS and scripts go decide wetin dem go suppress.
  • search-picker — icon button wey open search field; when you submit, e go navigate to search page. E own action, no be preference.
  • link-picker — home icon wey open menu of di page links wey your app define (Home, About Us, Contact Us, Privacy Policy, …). E own action, no be preference.
  • share-picker — e open di native share sheet or destination list wey consumer supply, plus copy-di-URL. E own action, no be preference: e no apply anything, e no persist anything.
  • date-time-picker — text field plus APG date-picker dialog for date, time, or both. E own form value, no be preference: di ISO string dey round-trip to <input type="date">.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-theme-picker

Di Svelte catalog na di canonical reference; React, Vue, Angular, HTML, Nunjucks, Web Components, and Blazor ports match am contract-for-contract. See di helpers tutorial.

Accessibility

Components target WCAG 2.2 AAA. Dem dey follow dis patterns:

  • Semantic HTML elements instead of generic <div>s.
  • <label for="id"> linking labels to inputs.
  • aria-labelledby / aria-describedby for cross-references.
  • aria-invalid + aria-errormessage for error states.
  • role="alert" and aria-live for dynamic content.
  • aria-pressed, aria-expanded, aria-current for state.
  • Roving tabindex for grids.

Focus indicators na consumer-supplied on purpose — Lily no dey ever paint default focus ring wey fit clash with your design. Di example apps dey keep clean axe-core baseline across their routes.

Internationalization

Every label, placeholder, error message, and button text na prop. No hardcoded strings dey. Put your translation framework of choice — Paraglide, i18next, vue-i18n, react-intl, .resx files, anything.

For dates, numbers, and currencies, di components dey accept pre-formatted strings: you go format with Intl.DateTimeFormat / Intl.NumberFormat / your preferred library and pass di result.

Di locale-picker helper dey signal di chosen locale to your i18n library by setting lang and dir for di document root.

Testing

Each framework subproject ship im own tests wey use im idiomatic stack:

  • HTML: WebDriverIO wey dey run real browsers.
  • Svelte: Vitest + @testing-library/svelte.
  • React: Vitest + @testing-library/react.
  • Vue: Vitest + @testing-library/vue.
  • Angular: Vitest + TestBed (through di Analog Vite plugin).
  • Nunjucks: Vitest with render helper.
  • Blazor: bUnit.

Tests dey use Vitest built-in matchers only — never jest-dom matchers. Dis one dey keep di test suites portable. Di example apps add Playwright end-to-end suites, axe-core accessibility baselines, and responsive viewport sweep.

AI agents

Dis site dey publish llms.txt and llms.json for im root — curated map of im most important pages, for any tool wey follow di llms.txt convention.

Di canonical monorepo also ship two Claude Skills: lily-design-system-skill, general-purpose skill wey cover Lily concepts, terminology, and composition patterns for anybody wey dey build with di system, and lily-design-system-maintainer-skill, technical skill wey cover di monorepo required-files layout and tooling for anybody wey dey work on am. Both dey for di root of di canonical monorepo.

Troubleshooting

Component render but e look unstyled

Na headless dey work as e suppose — no CSS ship with di component. Either write CSS against di component kebab-case class (wey show for every catalog page) or link one of di 57 ready-made themes.

My CSS no seem to apply over theme

E suppose — theme selectors dey wrapped in :where(...), wey get zero specificity. If rule still lose, check say your stylesheet load after di theme own <link> and say di selector really match di component class hook.

pnpm install fail with peer or version error

Use current pnpm (v10+) and Node 22+. Each subproject dey pin im framework versions for im own package.json; if your global toolchain old pass, pnpm env use --global lts na di quickest fix.

Screen reader announce wrong name for control

Check di component required label prop — components wey no get visible text require one, and consumer-supplied aria-label / aria-labelledby wey pass through rest-props dey win on purpose over di built-in wiring. Each catalog page dey document di component ARIA contract.

Di theme-picker helper no dey switch stylesheets

Confirm say themesUrl point to directory wey di browser fit fetch (serve di themes/ files as static assets) and say di theme slugs for your themes prop match di file names. Di helper dey swap di href of one managed <link data-lily-theme-picker> — inspect am for devtools to see di URL wey dem dey request.

Something else don break

Open issue with minimal reproduction for github.com/LilyDesignSystem/lily-design-system — or see community and support.

Contributing

Lily young and e welcome collaboration. Di most useful contributions right now na:

  • New components (especially patterns from established design systems).
  • New themes — each one na one standalone stylesheet, well-scoped first PR.
  • Better example styling — show wetin possible.
  • Translations of example app strings.
  • Bug reports with minimal reproduction.
  • Accessibility audits with screen readers and assistive tech.

Open issues and PRs for github.com/LilyDesignSystem/lily-design-system.

Community and support

FAQ

Why headless instead of styled?

Pre-styled components dey convenient — until dem no match your brand. Headless components na small extra work at first but dem give you total control of di visual design. Di example apps and di 57 themes show ways to style dem; you fit take those or replace dem completely. Di longer argument dey for Why Lily.

Why so many components?

Lily aim to cover di patterns wey most apps need without forcing you to build dem from scratch — including deep cuts like national identifier inputs and editorial scrollytelling. Di catalog dey draw from dozen established design systems plus original work — see About.

Can I use Lily with Tailwind?

Yes. Each component dey expose one kebab-case root class plus consumer-provided className / class. Layer Tailwind utilities on top how you like.

Can I use Lily with semantic CSS frameworks like DaisyUI?

Yes. Di kebab-case class names for di root element dey work as semantic CSS hooks. Pair Lily with semantic framework and you go get pre-styled components wey still respect ARIA and i18n.

Dey npm package?

Di preference helpers ship as packages with npm/NuGet publish pipeline. Di headless component libraries dem design am to clone or vendor — di source na di deliverable, so you fit read, trim, and own exactly wetin you ship. Registry publishing for di headless libraries still dey for di roadmap.

Why multi-licensed?

Different projects get different license needs. BSD and MIT dey permissive, Apache-2.0 get patent grant, and di GPL options support copyleft. Choose whichever fit your situation.

How I go report bug or request feature?

Open issue for di GitHub repository, or email joel@joelparkerhenderson.com.