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

@akonwi/mica

v0.15.0

Published

Custom elements. Native behavior. Nearly no JavaScript.

Readme

mica

Custom elements. Native behavior. Nearly no JavaScript.

Mica is a progressive component library of custom elements — progressive as in progressive enhancement: every component starts from markup that works, and each layer (CSS, the browser's native behavior, an optional JS module) enhances it. No runtime, no build step, no framework. View source — there's nothing there but HTML and a stylesheet.

<link rel="stylesheet" href="mica.css">

<m-vstack gap="lg">
  <h1>That's it</h1>
  <m-hstack gap="sm">
    <button data-variant="primary">Save</button>
    <button data-variant="ghost">Cancel</button>
  </m-hstack>
</m-vstack>

<m-vstack> is never registered — an unknown custom element is a valid, stylable element. The behavior everywhere else (dialogs, accordions, menus, form validation) comes from the browser, not from a runtime.

Getting it

Copy the file — mica is one dependency-free CSS file. Vendoring is a first-class distribution channel, not a workaround:

curl -O https://raw.githubusercontent.com/akonwi/mica/v0.2.1/mica.css

npm — for toolchains:

npm install @akonwi/mica
import "@akonwi/mica/mica.css";

CDN — for trying it out:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@akonwi/[email protected]/mica.css">

Progressive by design

Every component states where its behavior comes from (see PROGRESSIVE.md):

  • CSS-only — CSS is the behavior. Layout primitives: m-vstack, m-hstack, m-zstack, m-center, m-box, m-grid, m-sidecar, m-switcher, m-reel. Zero JS, work with JS disabled.
  • Native behavior — the browser is the behavior. Styled native elements: buttons, forms, <dialog>, <details> accordions, popover menus, tooltips, toasts. Delete the stylesheet and everything still works.
  • JS-enhanced — script, honestly. Where accessibility genuinely requires JS: tabs.js, combobox.js, field.js (declarative validation), select.js, toast.js, header.js, sidebar.js (responsive navigation). Each is a tiny standalone module that enhances working markup — never renders it. There is no shared runtime.

m-avatar accepts authored initials or a direct native img, both CSS-only. avatar.js is a separate opt-in visual enhancement: importing it locally derives deterministic color and features from the blobatar seed without a network request.

Your CSS always wins

All of mica ships inside @layer mica.*. Unlayered user CSS beats layered CSS by spec — overriding mica never requires specificity games. Theming is swapping token values (--hue, semantic color roles, spacing scale); dark mode is light-dark() — automatic, no classes.

Browser support

Mica targets Baseline widely-available. Newer features (anchor positioning, customizable select) are used behind graceful fallbacks — each component's docs page notes what degrades and how. Nothing breaks; some things get plainer.

Docs

akonwi.io/mica — every component, built with mica itself (view source). The demo is the whole library on one page.

Read VISION.md for the philosophy and PROGRESSIVE.md for how components are allowed to work.

License

MIT

Nested header navigation uses nav[data-navigation-menu] with native details/summary groups and authored [data-nav-panel] content. Import header.js for floating desktop panels and inline mobile disclosures. See the navigation menu docs.

Bottom navigation uses nav[data-bottom-nav] and native links, with optional consumer-authored icons. No JavaScript module is needed. See the bottom navigation docs for a shell that keeps content clear of the bar.

Breadcrumbs use nav[data-breadcrumbs] with an ordered list of links and a current-page label. Optional breadcrumbs.js enhances an authored ancestor disclosure. See the breadcrumbs docs.

Data collections compose native table[data-table], a stable filter/selection toolbar, and nav[data-pagination]. The app owns all data operations; optional table.js only adds overflow indicators to m-table-scroll. See the data table and pagination docs.

Inline alerts and guidance use CSS-only m-callout with neutral, success, warning, and danger treatments. Icons and actions are optional authored content; see callout docs.

Cards use CSS-only m-card with optional m-card-header, m-card-body, and m-card-footer parts. A flush body composes with native ul/ol[data-list] without double padding. Lists use inset dividers by default; data-dividers="none" opts out. See cards and lists.

Running tests

Install development dependencies with bun install and browser engines with bun run snapshot:setup, then run:

bun run test                  # all behavior, docs, and snapshot checks
bun run test -- sidebar       # one component
bun run test -- menu          # menu and menu-touch
bun run test -- field drawer  # multiple suites
bun run test -- --list        # available suites

The runner discovers tools/*-check.ts and tools/*.test.ts, builds the docs for browser checks, and starts a temporary server on port 8471 when needed. An existing server serving this checkout is reused and left running. Failures are collected and return a nonzero exit status. Snapshot baselines are never updated by tests; use bun run snapshot explicitly to accept intentional changes.