Tokens
Colour, type and spacing that adapt to their surroundings. A few design decisions, with the rest derived from them.
Use our agent skill to quickly build bespoke, accessible UIs on top of our contextual tokens, element styles, and React components.
npx loamui@latest initOne command in your React application: the package, the stylesheet, the checks and the agent skills. From nothing, npx loamui@latest create.
Real primitives. Try the controls.
The foundation
Use them together to build your own UI, from a single form to a whole product.
Colour, type and spacing that adapt to their surroundings. A few design decisions, with the rest derived from them.
Native HTML with considered defaults for typography, forms and links, respecting the user’s preferences.
Low-level React parts for behaviour and interaction. Compose them with your own markup to make what your product needs.
Build with the skill
Start with a framework and LoamUI installed. Add the skill, then describe what you want to build. Your agent checks the setup, composes the primitives and tests the result.
pnpm dlx skills@latest add loamui/loamui --skill loamui --agent claude-code --yesnpx --yes skills@latest add loamui/loamui --skill loamui --agent claude-code --yesyarn dlx skills@latest add loamui/loamui --skill loamui --agent claude-code --yesbunx skills@latest add loamui/loamui --skill loamui --agent claude-code --yesUse the LoamUI skill to build a restaurant menu with starter and dessert cards. Include three dishes in each, with descriptions and prices. Mark the starters as vegetarian and the desserts as sold out. Let me select the available course.
New project? Install LoamUI. For setup help, follow Build with the skill.
Explore the result
"use client"; import { useState } from "react";import { Badge, Button, Card } from "@loamui/core";import "./menu.css"; const courses = [ { title: "Starter", status: "vegetarian", label: "Vegetarian", dishes: [ ["Burrata", "Heritage tomatoes, basil oil, sourdough crumb", "£9.50"], ["Roast beetroot", "Whipped goat's curd, hazelnuts, dill", "£8.00"], ["Wild mushroom toast", "Garlic butter, parsley, poached egg", "£8.50"], ], }, { title: "Dessert", status: "sold-out", label: "Sold out", dishes: [ ["Sticky toffee pudding", "Date sponge, butterscotch, clotted cream", "£7.50"], ["Lemon posset", "Shortbread, raspberries", "£6.50"], ["Chocolate tart", "Salted caramel, crème fraîche", "£7.00"], ], },] as const; export function RestaurantMenu({ headingLevel = 2 }: { headingLevel?: 2 | 3 }) { const Heading = headingLevel === 2 ? "h2" : "h3"; const CourseHeading = headingLevel === 2 ? "h3" : "h4"; const [starterSelected, setStarterSelected] = useState(false); return ( <section className="menu"> <Heading>Menu</Heading> <p className="demo-note">Try a selection. This demo does not place an order.</p> {courses.map(({ title, status, label, dishes }) => ( <Card key={title}> <div className={`menu-card ${status}`}> <CourseHeading> {title}{" "} <Badge.Root> <Badge.Text>{label}</Badge.Text> </Badge.Root> </CourseHeading> <dl> {dishes.map(([name, description, price]) => ( <div key={name}> <dt> {name} <data value={price.slice(1)}>{price}</data> </dt> <dd>{description}</dd> </div> ))} </dl> <footer> <Button disabled={status === "sold-out"} onClick={() => setStarterSelected((selected) => !selected)} > {status === "sold-out" ? "Dessert unavailable" : starterSelected ? "Remove starter" : "Add starter"} </Button> </footer> </div> </Card> ))} <p className="selection" role="status"> {starterSelected ? "Starter added to your demo selection." : "No courses selected."} </p> </section> );}
@layer loamui.components { @scope (.menu) to ([class*="loam-"]) { :scope { container-type: inline-size; display: block grid; gap: var(--loam-space-s); grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); } :scope > :is(h2, h3), p.demo-note, p.selection { grid-column: 1 / -1; margin: 0; } } @scope (.menu-card) to ([class*="loam-"]) { :scope { block-size: 100%; container-type: inline-size; display: block grid; gap: var(--loam-space-s); grid-template-rows: auto 1fr auto; /* The card's status is a fact about the region: the Badge and the Button inside read it, nothing is passed to them as a prop */ &.vegetarian { --loam-context: success; } &.sold-out { --loam-context: danger; } } footer { display: block grid; } :is(h3, h4) { align-items: baseline; display: block flex; flex-wrap: wrap; gap: var(--loam-space-2xs); margin: 0; } dl { align-content: start; display: block grid; gap: var(--loam-space-2xs); margin: 0; } dt { display: block flex; font-weight: 600; gap: var(--loam-space-2xs); justify-content: space-between; } dd { color: var(--loam-color-fg-muted); font-size: var(--loam-text-sm); margin: 0; } data { font-variant-numeric: lining-nums tabular-nums; } }}
The cards compose tokens, native element styles, Badge and Button. Open the React or CSS tab to see how they fit together.
Pillar 1 · Modern Web
Google’s Modern Web Guidance and Modern CSS inform how we build all three primitives. Native behaviour comes first, with enhancements where the browser supports them.
Real buttons, inputs and dialogs supply their semantics and platform behaviour.
New capabilities build on usable defaults. Motion is added when the user permits it.
Baseline guides feature adoption. Newer capabilities have a usable fallback.
Declare a region’s meaning once. Its tokens adapt, and the native elements and components using them follow. Available space shapes type and spacing in the same way.
Change the region’s meaning or available space. The same elements and components adapt through LoamUI’s tokens and CSS.
Explore contextualismThe same content adapts to its surroundings.
How contextualism worksWide container · Neutral context
Wide fits the space available on your screen.
Pillar 2 · Accessibility & UX
We draw on the GOV.UK and Polaris design systems for decisions that help people use your interface. Each component’s documentation explains when to use it and why.
Read the accessibility guidanceConfidence in the result
The skill guides the work; checks help you review it. Our primitives are tested in CI. Your composition still needs validation with its own content, layout and interactions.
The skill checks the package, stylesheet and project setup before composing your UI.
Use TypeScript, Stylelint and automated accessibility checks, then exercise the interactions.
Inspect narrow layouts, both themes and keyboard use. Judge the copy and visual result.
Build with LoamUI
Contextual tokens, native element styles and composable React parts, with an agent skill to bring them together. Modern web foundations and considered UX, ready for your next project.
Get started