npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arc-lang/arc-ui

v2.4.1

Published

Liquid glass UI component library — 49 components, CSS-first, arc-animations integration. Zero dependencies.

Readme

arc-ui

version components JS size dependencies license Part of Arc

Liquid glass UI component library. 17 components, CSS-first, zero dependencies. Configurable via CSS custom properties — change 6 vars to retheme everything.

Part of Arc — the zero-dependency web framework.

vs. alternatives: | Library | Size | Framework | Deps | |---|---|---|---| | Headless UI | ~8KB | React only | React | | Radix UI | ~20KB+ | React only | React | | Floating UI | ~10KB | any | none | | arc-ui | ~3KB | any | none |


Install

npm install arc-ui

CDN:

<link rel="stylesheet" href="https://unpkg.com/arc-ui/index.css">

Glass Design System

arc-ui v2.0 introduces a single configurable token system. Every component inherits from these vars — change them once, retheme everything.

:root {
  /* Glass surface */
  --glass-bg:        rgba(255, 255, 255, 0.10);
  --glass-bg-hover:  rgba(255, 255, 255, 0.16);
  --glass-blur:      20px;
  --glass-saturate:  180%;
  --glass-border:    rgba(255, 255, 255, 0.25);
  --glass-shadow:    0 8px 32px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.18);

  /* Accent */
  --ui-accent:       #5956f0;

  /* Timing */
  --ui-duration:     var(--anim-duration, 0.2s);  /* auto-inherits arc-animations */
  --ui-easing:       var(--anim-easing, cubic-bezier(0.16, 1, 0.3, 1));
}

arc-animations integration

Three tiers — all CSS, no JS:

Tier 1 — Timing inheritance (automatic) Load arc-animations before arc-ui. --ui-duration picks up --anim-duration automatically via CSS var fallback.

Tier 2 — Class composability

<div class="card animate-float-in">...</div>

Tier 3 — Animation override vars

:root {
  --modal-enter-animation: zoom-in;   /* any arc-animations keyframe */
  --toast-enter-animation: slide-right;
}

Components

Pure CSS (no JS)

| Component | File | Description | |---|---|---| | Accordion | src/accordion.css | <details>/<summary>, height animation | | Tooltip | src/tooltip.css | data-tooltip attribute, 4 positions | | Switch | src/switch.css | <input type="checkbox"> styled | | Progress | src/progress.css | --progress-value CSS var, circular SVG | | Skeleton | src/skeleton.css | Shimmer animation, prebuilt shapes | | Badge | src/badge.css | Color variants, dot indicator | | Alert | src/alert.css | 4 semantic variants | | Spinner | src/spinner.css | Ring, dots, pulse variants | | Avatar | src/avatar.css | Image or initials, stack group | | Card | src/card.css | Glass surface, image/body/footer |

Requires small JS (~300B each)

| Component | CSS | JS | Description | |---|---|---|---| | Button | src/button.css | — | All variants (loading state via CSS) | | Modal | src/modal.css | js/modal.js | Native <dialog>, focus trap | | Toast | src/toast.css | js/toast.js | Toast.show() API | | Tabs | src/tabs.css | js/tabs.js | ARIA tabs, keyboard nav | | Dropdown | src/dropdown.css | js/dropdown.js | Toggle, keyboard nav, ui:select event | | Drawer | src/drawer.css | js/drawer.js | Slide panel, focus trap, Escape | | Input | src/input.css | — | input/textarea/select, icon addon |


Button

<button class="btn">Default</button>
<button class="btn btn--primary">Primary</button>
<button class="btn btn--ghost">Ghost</button>
<button class="btn btn--outline">Outline</button>
<button class="btn btn--danger">Danger</button>
<button class="btn btn--sm">Small</button>
<button class="btn btn--lg">Large</button>
<button class="btn is-loading">Loading</button>

| CSS property | Default | Description | |---|---|---| | --btn-radius | var(--ui-radius) | Border radius | | --btn-padding | 9px 18px | Padding | | --btn-font-size | 14px | Font size |


Modal

Native <dialog> element — backdrop, Escape key, and browser accessibility built in.

<dialog class="modal" id="my-modal">
  <div class="modal__box">
    <button class="modal__close" data-modal-close aria-label="Close">&#10005;</button>
    <div class="modal__header">
      <h2 class="modal__title">Confirm</h2>
      <p class="modal__subtitle">Are you sure?</p>
    </div>
    <div class="modal__footer">
      <button class="btn btn--ghost" data-modal-close>Cancel</button>
      <button class="btn btn--primary" data-modal-close>Confirm</button>
    </div>
  </div>
</dialog>

<button data-modal-open="my-modal">Open</button>
<script src="https://unpkg.com/arc-ui/js/modal.js"></script>

| CSS property | Default | Description | |---|---|---| | --modal-width | 540px | Dialog width | | --modal-radius | var(--ui-radius-xl) | Border radius | | --modal-bg | rgba(255,255,255,0.88) | Glass background | | --modal-blur | 40px | Backdrop blur | | --modal-enter-animation | modal-in | Entrance keyframe name |


Toast

Toast.show('Saved!', { type: 'success', icon: '✓' })
Toast.show('Error occurred', { type: 'error', duration: 0 }) // persistent
Toast.show('Warning', { type: 'warning' })
Toast.show('Info message', { type: 'info' })
<script src="https://unpkg.com/arc-ui/js/toast.js"></script>

| Option | Default | Description | |---|---|---| | type | '' | success / error / warning / info | | duration | 4000 | Auto-dismiss in ms. 0 = persistent | | icon | '' | Icon string prepended to message |

| CSS property | Default | |---|---| | --toast-enter-animation | toast-in | | --toast-bg | rgba(20,24,36,0.88) | | --toast-radius | var(--ui-radius-lg) |


Dropdown

<details class="dropdown">
  <summary class="btn dropdown__trigger">Options ▾</summary>
  <div class="dropdown__menu" role="menu">
    <div class="dropdown__label">Actions</div>
    <button class="dropdown__item" data-value="edit">
      <span class="dropdown__icon">✏</span> Edit
      <span class="dropdown__shortcut">⌘E</span>
    </button>
    <div class="dropdown__separator"></div>
    <button class="dropdown__item dropdown__item--danger" data-value="delete">Delete</button>
  </div>
</details>
<script src="https://unpkg.com/arc-ui/js/dropdown.js"></script>

Uses native <details> — click-outside and Escape close for free (no JS). JS adds keyboard nav (↑/↓/Tab) and dispatches ui:select CustomEvent: { value, label, item }.

Variants: .dropdown--right, .dropdown--up.


Drawer

<button data-drawer-open="my-drawer">Open</button>

<div class="drawer-overlay" data-for="my-drawer"></div>
<aside class="drawer" id="my-drawer" aria-hidden="true">
  <div class="drawer__header">
    <h2 class="drawer__title">Title</h2>
    <button class="drawer__close" data-drawer-close>✕</button>
  </div>
  <div class="drawer__body">Content</div>
  <div class="drawer__footer">
    <button class="btn btn--ghost" data-drawer-close>Cancel</button>
    <button class="btn btn--primary">Save</button>
  </div>
</aside>
<script src="https://unpkg.com/arc-ui/js/drawer.js"></script>

Variants: .drawer--left, .drawer--bottom (bottom sheet). Bottom sheet gets .drawer__handle (drag indicator).

Fires ui:drawer-open / ui:drawer-close CustomEvents.

| CSS property | Default | |---|---| | --drawer-width | 320px | | --drawer-bg | rgba(255,255,255,0.88) | | --drawer-blur | 32px | | --drawer-duration | var(--ui-duration-slow) |


Input

<div class="input-group">
  <label class="input-label" for="email">Email</label>
  <div class="input-wrap">
    <span class="input-icon">✉</span>
    <input class="input" id="email" type="email" placeholder="[email protected]">
  </div>
  <span class="input-hint">We'll never share this.</span>
</div>

<!-- Error state -->
<div class="input-group is-invalid">
  <label class="input-label">Password</label>
  <input class="input" type="password">
  <span class="input-hint">Must be at least 8 characters</span>
</div>

<select class="select">...</select>
<textarea class="textarea" rows="4"></textarea>

Switch

<label class="switch-label">
  <input type="checkbox" class="switch" checked>
  Enable notifications
</label>

Sizes: .switch--sm, .switch--lg. Zero JS.


Progress

<!-- Linear — set --progress-value (0–100) -->
<div class="progress" style="--progress-value:72">
  <div class="progress__bar"></div>
</div>

<!-- Indeterminate -->
<div class="progress progress--indeterminate">
  <div class="progress__bar"></div>
</div>

<!-- Circular SVG ring -->
<div class="progress-ring" style="--progress-value:65">
  <svg viewBox="0 0 56 56" class="progress-ring__svg">
    <circle class="progress-ring__track" cx="28" cy="28" r="24"/>
    <circle class="progress-ring__fill"  cx="28" cy="28" r="24"/>
  </svg>
  <span class="progress-ring__label">65%</span>
</div>

Zero JS — --progress-value drives width/stroke-dashoffset via CSS calc.


Avatar

<!-- Initials -->
<span class="avatar">AB</span>
<span class="avatar avatar--lg avatar--purple">GH</span>

<!-- Image -->
<span class="avatar"><img src="photo.jpg" alt="Jane"></span>

<!-- With status -->
<div class="avatar-wrap">
  <span class="avatar avatar--lg">JD</span>
  <span class="avatar-status avatar-status--online"></span>
</div>

<!-- Stack group -->
<div class="avatar-stack">
  <span class="avatar avatar--sm">AB</span>
  <span class="avatar avatar--sm avatar--purple">CD</span>
  <span class="avatar avatar--sm avatar--pink">EF</span>
</div>

Sizes: --xs (24px), --sm (32px), default (40px), --lg (56px), --xl (80px). Color presets: --purple, --pink, --orange, --teal.


Tabs

<div class="tabs">
  <div class="tabs__list" role="tablist">
    <button class="tabs__tab is-active" role="tab" aria-selected="true" data-tab="panel-1">Tab 1</button>
    <button class="tabs__tab" role="tab" aria-selected="false" data-tab="panel-2">Tab 2</button>
  </div>
  <div class="tabs__panel is-active" id="panel-1" role="tabpanel">Content 1</div>
  <div class="tabs__panel" id="panel-2" role="tabpanel">Content 2</div>
</div>
<script src="https://unpkg.com/arc-ui/js/tabs.js"></script>

Variants: .tabs--pills (glass pill), .tabs--boxed.


Accordion

<div class="accordion">
  <details class="accordion__item">
    <summary class="accordion__trigger">Question?</summary>
    <div class="accordion__content">Answer.</div>
  </details>
</div>

Zero JS. Height animates in Chrome 129+ via interpolate-size: allow-keywords. Add .accordion--flush for separator-only style.


Alert

<div class="alert alert--success">
  <span class="alert__icon">✓</span>
  <div>
    <div class="alert__title">Success</div>
    <div class="alert__text">Changes saved.</div>
  </div>
</div>

Variants: alert--info, alert--success, alert--warning, alert--error.


Skeleton

<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--title"></div>
<div class="skeleton skeleton--avatar"></div>
<div class="skeleton skeleton--card"></div>

Static gray on prefers-reduced-motion.


Badge

<span class="badge badge--success">Active</span>
<span class="badge badge--error"><span class="badge__dot"></span>Offline</span>

Variants: --accent, --success, --error, --warning, --info, --glass. Sizes: --sm, --lg.


Spinner

<span class="spinner"></span>
<span class="spinner spinner--dots"></span>
<span class="spinner spinner--pulse"></span>

Sizes: --sm, --lg.


Tooltip

<button data-tooltip="Save document">Save</button>
<button data-tooltip="Delete" class="tooltip--below">Delete</button>
<button data-tooltip="Help" class="tooltip--right">?</button>
<button data-tooltip="Light glass" class="tooltip--light">Light</button>

Zero JS. Positions: default (above), .tooltip--below, .tooltip--left, .tooltip--right.

| CSS property | Default | |---|---| | --tooltip-bg | rgba(20,24,36,0.88) | | --tooltip-blur | 12px | | --tooltip-delay | 0.15s |


Tree-shaking

Import only what you need:

<link rel="stylesheet" href="https://unpkg.com/arc-ui/src/base.css">
<link rel="stylesheet" href="https://unpkg.com/arc-ui/src/button.css">
<link rel="stylesheet" href="https://unpkg.com/arc-ui/src/modal.css">

Browser support

| Feature | Chrome | Firefox | Safari | Edge | |---------|--------|---------|--------|------| | backdrop-filter | 76+ | 103+ | 9+ | 79+ | | <dialog> | 37+ | 98+ | 15.4+ | 79+ | | <details>/<summary> | 12+ | 49+ | 6+ | 79+ | | Height animation (interpolate-size) | 129+ | — | — | 129+ | | CSS custom properties | 49+ | 31+ | 9.1+ | 15+ |

Graceful degradation: backdrop-filter unsupported = opaque background. Height animation unsupported = instant expand/collapse.


Accessibility

  • Modal: focus trapped (Tab/Shift-Tab), Escape closes, native <dialog> semantics
  • Dropdown: native <details>/<summary> (Escape + click-outside free), //Tab keyboard nav, role="menu"
  • Drawer: focus trap, Escape closes, body scroll locked, aria-hidden
  • Tabs: full ARIA (role="tablist", aria-selected), ←/→/Home/End navigation
  • Accordion: native <details>/<summary> — full browser keyboard + screen reader support
  • Switch: native <input type="checkbox"> — full keyboard, screen reader, and form support
  • Tooltip: :focus-visible triggered (keyboard accessible), not just :hover
  • prefers-reduced-motion: all animations instant, skeleton shimmer static

License

MIT © Arc contributors