Components that ship behavior, not opinions
What this library commits to
Accessibility first
Every component ships its WAI-ARIA pattern in full: roles, keyboard, focus. Restyling cannot turn it off.
Headless structure, overridable
The hz-* classes and data-* hooks hand you the styling; snippets hand you the markup. Both are documented API.
Theming is opt-in, one tier at a time
Tokens, the reference theme, your own overrides, or a generated sheet. Stop at any tier.
What it weighs
| What you import | Download (gzipped) | Uncompressed | What that includes |
|---|---|---|---|
| Every component, minified | 52.4 kB | 241 kB | A real build of the whole library, carrying only the few icons the components draw. Import three components and you ship a fraction of this. |
| Component structural CSS | 5.9 kB | 40.1 kB | Layout and behavior only. No colors or other visual styling. |
| Design tokens | 3.2 kB | 12.0 kB | The --hz-* custom properties, also called CSS variables. |
| Reference theme | 50.2 kB | 146 kB | One import for the shared base sheet plus a sheet per component. Import single component sheets instead and you pay less. |
| Reset | 1.3 kB | 2.4 kB | Optional. Structural only. |
| Utilities | 1.7 kB | 6.8 kB | Helper classes you import only if you want them. |
| Everything, together | 115 kB | 448 kB |
Gzipped is what crosses the network. Uncompressed is what the browser holds once it unzips the file.
The first row is the ceiling for JavaScript, not for the total: you will always add at least the token sheet on top of it. Your bundler keeps only the components you import, so three components cost a fraction of that row. The reference theme works the same way. You can import one component sheet at a time instead of the whole thing. The token, reset and utility figures are exact, because you import each of those sheets whole.
1 dependency (build-time only), with svelte as the only peer dependency.
Install
pnpm add @hyzer-labs/ui@import '@hyzer-labs/ui/tokens.css';
@import '@hyzer-labs/ui/theme';
@import '@hyzer-labs/ui/utilities.css'; /* optional */- Svelte 5.32 or newer.
- Node 22.18 or newer. Only the
hyzerCLI needs it. - TypeScript is optional. Types ship with the package.
- SvelteKit is optional. The library imports nothing from Kit.
Then import a component and render it. The code below is a whole file. Beside it is that same file, rendered with the reference theme.
<script>
import { Card, Badge, Button } from '@hyzer-labs/ui';
</script>
<Card padding="sm" class="conditions">
<strong>Maple Hill</strong>
<span class="muted">18 holes · open at dawn</span>
<Badge intent="success">Greens fast</Badge>
<Badge intent="warning">Wind picking up</Badge>
{#snippet actions()}
<Button size="sm">Book a tee time</Button>
{/snippet}
</Card>
<style>
/* The class prop lands on the component root, but Svelte scopes
selectors to elements in your own markup, so target it with
:global. */
:global(.conditions) {
background: var(--hz-color-surface-muted);
max-inline-size: 24rem;
}
.muted {
display: block;
color: var(--hz-color-text-muted);
margin-block-end: 0.75rem;
}
</style>