Installation
Two packages, released together under one version: the tokens, which any stack can use, and the React components built on them. Five steps from an empty app to a first component.
1. Install the packages
Node 22.18 or later, React 19.2 or later. The components depend on the tokens and on Base UI, which npm installs with them.
npm install @orbex/sonar-tokens@1.1.6 @orbex/sonar-components@1.1.6 react react-dom
2. Set the cascade layers
The system’s styles live in one cascade layer, sonar, with sonar.tokens and
sonar.components inside. Declare the order once, before any stylesheet loads, so a reset can never
override the system and the app’s own styles always win without !important.
/* Once, before any stylesheet (a <style> at the top of <head> is safest, since bundlers may reorder files):
the order of the layers. The system sits under one name, sonar: after any reset, before the app’s own styles. */
@layer reset, sonar, app;
3. Import the tokens
/* At the root of the app, once: every token as a CSS custom property, in both themes */
@import '@orbex/sonar-tokens/tokens.css';
/* Optional: the type roles as classes (.sonar-type-title-md …) */
@import '@orbex/sonar-tokens/type.css';
Style with role tokens, which describe what a value is for and change with the theme. Palette tokens stay underneath: a component never reads them.
.delivery-card {
background: var(--sonar-color-surface-card);
border-radius: var(--sonar-shape-corner-medium);
box-shadow: var(--sonar-elevation-1);
color: var(--sonar-color-text-default);
padding: var(--sonar-space-16) var(--sonar-space-20);
}
Both themes ship in the same file. Without an attribute, the system follows the operating system;
data-theme forces a theme on an element and everything inside it.
<!-- Follows the operating system by default. Force a theme on any element and everything inside it -->
<html data-theme="dark">
<aside data-theme="light">…</aside>
4. Use a component
Each component is its own entry point with its own stylesheet, so an app loads only what it uses. All 24 weigh 47.8 KB gzipped together, script and styles.
import { Button } from '@orbex/sonar-components/button'
import '@orbex/sonar-components/button.css'
export function PlaceOrder() {
return <Button onClick={() => console.log('Order placed')}>Place order</Button>
}
/* Apps that use most components: every component’s styles in one file */
import '@orbex/sonar-components/styles.css'
import { Button } from '@orbex/sonar-components/button'
import { Status } from '@orbex/sonar-components/status'
Components take icons as elements: the Icons page shows how to make one from Material Symbols.
5. Read tokens and props from code
The tokens are also typed data, for scripts, charts and tools. The props of every component are published as
JSON, in the package as @orbex/sonar-components/api.json and on this site at
/api.json; /llms.txt describes the whole system for coding agents.
import { tokens, sizeClasses } from '@orbex/sonar-tokens'
/* Every token with its CSS variable, description and value in each theme */
const accent = tokens.find((token) => token.name === 'color.accent')
/* The window size classes, with a media query for each */
const compact = matchMedia(sizeClasses[0].media).matches