Documentation
Installation
Install Luke UI and a theme, and render a component.
Install Luke UI
Install Luke UI, React Aria Components, and a theme. Luke UI uses the application's React Aria Components instance so shared contexts remain compatible. Luke UI needs React and React DOM 19.3.0 or later within React 19, and its type declarations need TypeScript 5.8 or later. This guide uses the Tactile theme.
pnpm add @luke-ui/react @luke-ui/theme-tactile react-aria-componentsSet up the theme
The theme's identity class goes on <html>, and it must be there before the first paint. How you
set it depends on whether React renders the whole document.
Luke UI's shared stylesheet paints <body> with the theme's surface, text colour, and body font,
and portals rendered into <body> inherit them. Read Styling
for what else it changes.
Single-page apps
In a Vite app, or any app that mounts React into an existing page, set the identity class in
index.html:
<!doctype html>
<html class="luke-ui-theme-tactile" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My app</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>Import the stylesheets in the entry module. fonts.css loads the theme's Inter font. Leave it out
if you load Inter another way.
import '@luke-ui/react/stylesheet.css';
import '@luke-ui/theme-tactile/fonts.css';
import '@luke-ui/theme-tactile/stylesheet.css';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Welcome } from './welcome.tsx';
const container = document.getElementById('root');
if (container === null) throw new Error('index.html has no #root element');
createRoot(container).render(
<StrictMode>
<Welcome />
</StrictMode>,
);Frameworks that render the document
When React renders <html> and <body>, as in Next.js, React Router, or TanStack Start, set the
identity class in the root layout. The server then sends it in the first HTML.
import '@luke-ui/react/stylesheet.css';
import '@luke-ui/theme-tactile/fonts.css';
import '@luke-ui/theme-tactile/stylesheet.css';
import { themeClassName } from '@luke-ui/theme-tactile';
import type { PropsWithChildren } from 'react';
export function RootLayout({ children }: PropsWithChildren) {
return (
<html className={themeClassName} lang="en">
<body>{children}</body>
</html>
);
}Use components
Import each component from its package path.
import { Button } from '@luke-ui/react/button';
import { Text } from '@luke-ui/react/text';
export function Welcome() {
return (
<>
<Text>Welcome to Luke UI.</Text>
<Button>Continue</Button>
</>
);
}Content Security Policy
The stylesheet draws the built-in icons from data: image URLs. If your application sets a Content
Security Policy, allow them in img-src:
Content-Security-Policy: img-src 'self' data:Without data:, the browser blocks the icons and they do not appear.
Change the theme
Paper uses the same component APIs with a flatter visual treatment. To use it, install
@luke-ui/theme-paper, import its stylesheet.css and fonts.css instead of Tactile's, and set
luke-ui-theme-paper on <html>. Each theme package exports its class as themeClassName.
Without data-color-mode, the theme follows the system colour mode. Read
Applying a theme to set a mode.