Help
Getting started with Lily
Pick a framework, clone the headless repo or the example app, and start composing your own pages.
Install
Lily is published as separate Git repos per framework. The fastest way to try it is to clone the headless repo for your stack:
git clone https://github.com/LilyDesignSystem/lily-design-system-react-headless
cd lily-design-system-react-headless
pnpm install The same pattern works for the other frameworks:
lily-design-system-html-headless— no install needed; copy.htmlfileslily-design-system-svelte-headless—pnpm installlily-design-system-react-headless—pnpm installlily-design-system-vue-headless—pnpm installlily-design-system-nunjucks-headless—pnpm installlily-design-system-blazor-headless—dotnet build(in progress)
Lily is being released bit-by-bit; npm/PyPI/NuGet packaging is on the roadmap. For now, treat the source as the source of truth and copy what you need.
Use a headless component
Headless components ship semantic HTML, ARIA, and props — but no CSS. Here's a Button in 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> Nunjucks
{% from "components/button/macro.njk" import button %}
{{ button({ text: "Save", type: "button" }) }}Use a styled example
The example apps include CSS, routes, and full demo pages. The fastest way
to experiment is to start the SvelteKit, Next, Nuxt, or Eleventy example
app and view the demo at /components.
git clone https://github.com/LilyDesignSystem/lily-design-system-svelte-sveltekit-examples
cd 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 renders with a single kebab-case class on its root element.
For example, <Button> renders <button class="button">.
Style it however 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); } The default Lily color palette (used in the example apps) is:
- Primary:
#2563eb - Danger:
#dc2626 - Warning:
#f59e0b - Success:
#16a34a - Page background:
#f9fafb - Card background:
#ffffff
These are suggestions, not requirements. Replace them with your own brand palette and Lily comes along happily.
Accessibility
Components target WCAG 2.2 AAA. They follow these patterns:
- Semantic HTML elements over generic
<div>s. <label for="id">linking labels to inputs.aria-labelledby/aria-describedbyfor cross-references.aria-invalid+aria-errormessagefor error states.role="alert"andaria-livefor dynamic content.aria-pressed,aria-expanded,aria-currentfor state.- Roving
tabindexfor grids.
Focus indicators are intentionally consumer-supplied — Lily never paints a default focus ring that conflicts with your design.
Internationalization
Every label, placeholder, error message, and button text is a prop. There are no hardcoded strings. Drop in your translation framework of choice — Paraglide, i18next, vue-i18n, react-intl, .resx files, anything.
For dates, numbers, and currencies, the components accept pre-formatted
strings: you format with Intl.DateTimeFormat / Intl.NumberFormat / your preferred library and pass the result.
Testing
Each framework subproject ships its own tests using its idiomatic stack:
- HTML: WebDriverIO running real browsers.
- Svelte: Vitest +
@testing-library/svelte. - React: Vitest +
@testing-library/react. - Vue: Vitest +
@testing-library/vue. - Nunjucks: Vitest with a render helper.
- Blazor: bUnit (planned).
Tests use Vitest's built-in matchers only — never jest-dom matchers. This keeps the test suites portable.
Contributing
Lily is brand-new and welcomes collaboration. The most useful contributions right now are:
- New components (especially patterns from established design systems).
- Better example styling — show off what's possible.
- Translations of example app strings.
- Bug reports with a minimal reproduction.
- Accessibility audits with screen readers and assistive tech.
Open issues and PRs against the relevant repo at github.com/LilyDesignSystem.
FAQ
Why headless instead of styled?
Pre-styled components are convenient — until they don't match your brand. Headless components are slightly more work up front but give you total control over the visual design. The example apps show one way to style them; you can take that or replace it entirely.
Why so many components?
Lily aims to cover the patterns most apps need without forcing you to build them from scratch. The catalog draws from a dozen established design systems plus original work — see About.
Can I use Lily with Tailwind?
Yes. Each component exposes a single kebab-case root class plus a
consumer-provided className / class. Layer
Tailwind utilities on top however you like.
Can I use Lily with semantic CSS frameworks like DaisyUI?
Yes. The kebab-case class names on the root element work as semantic CSS hooks. Pair Lily with a semantic framework and you get pre-styled components that still respect ARIA and i18n.
Is there an npm package?
Not yet. The headless repos are intended to be cloned and used directly, or vendored into your project. npm/PyPI/NuGet publishing is on the roadmap.
Why multi-licensed?
Different projects have different license needs. BSD and MIT are permissive, Apache-2.0 has a patent grant, and the GPL options support copyleft. Choose whichever fits your situation.
How do I report a bug or request a feature?
Open an issue on the relevant GitHub repo, or email joel@joelparkerhenderson.com.