ranui

A UI library built on native custom elements. Every component is an <r-*> tag, so it works in React, Vue, Svelte, Solid, Astro or a plain HTML file the same way. There is no adapter and no framework version to match. TypeScript types, light/dark theming through design tokens, Shadow DOM encapsulation and server rendering are included.

v0.5.0-alpha.7MITesm · cjs · iifepackages/ranui

  • ranui is alpha: versions ship breaking changes. Pin an exact version and read the changelog before upgrading.

Install

npm install ranui
<!-- or from a CDN, no build step -->
<script src="https://unpkg.com/ranui/dist/umd/index.umd.cjs"></script>

Use it

Importing registers the elements; after that you write tags.

import 'ranui'; // every component
import 'ranui/button'; // or just one
<r-button type="primary">Deploy project</r-button>

It is the same tag in every framework: the differences are in how each one passes values and binds events, which the coding guidelines cover in full:

<script src="https://unpkg.com/ranui/dist/umd/index.umd.cjs"></script>

<body>
  <r-button>Button</r-button>
</body>

Entry points

Each entry registers exactly what its name says, so a page that only wants theming never pays for the component library.

Import Contains
ranui Every component
ranui/<component> One component: ranui/button, ranui/select, …
ranui/theme Light/dark theming and token overrides; no elements
ranui/i18n The translation engine; no elements
ranui/fonts Self-hosted Geist Sans + Geist Mono
ranui/style The stylesheet, if your setup does not pick it up
ranui/builder The fluent DOM builder with fine-grained reactivity
ranui/ssr, ranui/ssr-stream Server rendering
ranui/testing Helpers for reaching into a closed shadow root from a test
ranui/typings Ambient JSX / TS element types

Components

40 elements. Every one of them, with its attributes, properties, events, slots and ::part() names, is in the element API reference.

Common: Button · Icon · Loading

Data entry: Input · CheckBox · Select · ColorPicker · Attachments · VoiceButton · Forms

Data display: Card · Section · Tabs · Image · Progress · Radar · Player · Preview · Glass · Scratch · StateDot · DisclosureRow

Content rendering: Markdown · Math · Mermaid

AI & chat: Conversation · Reasoning · ToolCard · TokenMeter

Overlays & feedback: Modal · Popover · Dropdown · Message · Skeleton

Navigation: Router · Route · Link

Foundations: Theming · ThemeSwitch · i18n

Five elements have no page of their own because they only exist inside another: <r-option> (Select), <r-tabs> (Tabs), <r-img> (Image), <r-dropdown-item> (Dropdown) and <r-content> (Popover). They are in the API reference like everything else.

Live

Primary Warning Text Default

Styling

Components render into a closed shadow root: page CSS cannot leak in, and selectors cannot reach through. There are four ways in, in order of preference.

1. Design tokens (CSS custom properties): they inherit across the boundary, so setting one on :root, on a wrapper or on the element all work:

<r-progress
  percent="0.7"
  type="drag"
  style="--ran-progress-track-background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f)"
></r-progress>

2. ::part() for structural tweaks the tokens do not cover · 3. the sheet attribute to inject CSS into the shadow root · 4. slotted content, which stays in your document and takes your page CSS.

The token names are the design system; the rules for choosing between them are the design guidelines; the mechanics are in the coding guidelines.

Events

Components dispatch CustomEvents with the payload in detail. Bind on the element: whether an event bubbles is a per-component decision, and the API reference states it for every one:

<r-select id="env"></r-select>

<script>
  document.getElementById('env').addEventListener('change', (event) => {
    console.log(event.detail.value);
  });
</script>

The onchange="…" attribute form and the el.onchange = … property form both work, since these are ordinary DOM elements, but they allow only one handler and no capture phase, so addEventListener is the one to reach for.

Where to go next

If you want to… Read
Look up an element's exact API Element API
Know which token to use, and why Design system
Build a screen that looks like one system Design guidelines
Wire ranui into an app correctly Coding guidelines
Add light/dark, or restyle everything Theming
Translate the interface i18n
Render on a server Server rendering
Build reactive views without a framework Builder
See what changed before upgrading Changelog

Browser support

The library works in every modern browser: it is built on Custom Elements v1, Shadow DOM v1 and CSS custom properties. Internet Explorer is not supported.

Contributors

Further reading

Standards this library is built on: W3C · ECMA · RFCs · Can I use

Design references worth keeping open: Checklist Design · Laws of UX · Geist · Ant Design · Element UI · Animista · WebGradients