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

kikiui-html

v0.2.0

Published

KIKI UI HTML: the vanilla HTML, CSS and JavaScript edition of the KIKI UI design system. Tokens, CSS-only components and lightweight, accessible behaviours you can load one component at a time. No React, no Tailwind, no runtime dependencies.

Readme

KIKI UI HTML · kikiui-html

The vanilla HTML / CSS / JavaScript edition of the KIKI UI design system.

Accessible, themeable components for websites that don't use React or Tailwind: static HTML sites, server-rendered templates (PHP, Django, Rails, …), WordPress and other CMS themes, Vite HTML projects, or any bundler. Use one component or the whole library.

  • No React, no Tailwind, no JSX, no build step required. Plain <link> and <script> tags work.
  • Zero runtime dependencies. Browser APIs only.
  • Independent package. kikiui-html does not depend on, and is not part of, the React package ui-kiki. It shares KIKI's visual language, not code.

Status: 0.1.0 release candidate, not yet published to npm.

Installation

npm install kikiui-html

Or copy the files in node_modules/kikiui-html/dist/ into your site. No build step is needed.

Usage

Plain HTML: everything

<link rel="stylesheet" href="node_modules/kikiui-html/dist/kiki.css">
<script src="node_modules/kikiui-html/dist/kiki.js" defer></script>

<button class="kiki-button kiki-button-primary">Get started</button>

kiki.css contains the tokens and every component. kiki.js adds every behaviour, exposes one global window.Kiki, and initialises itself on DOMContentLoaded. Minified versions: kiki.min.css and kiki.min.js.

Kiki.toast.success("Saved successfully");
Kiki.toast.error("Something went wrong");
Kiki.modal.open("example-modal");
const ok = await Kiki.modal.confirm({ title: "Delete project?", tone: "danger" });
Kiki.theme.set("dark");

Plain HTML: only what you need

Every page needs tokens.css once. Each component then adds its own stylesheet, plus one small script if it is interactive.

<!-- Button: CSS only -->
<link rel="stylesheet" href="node_modules/kikiui-html/dist/tokens/tokens.css">
<link rel="stylesheet" href="node_modules/kikiui-html/dist/components/button.css">

<!-- Modal: its stylesheet + its script -->
<link rel="stylesheet" href="node_modules/kikiui-html/dist/components/modal.css">
<script src="node_modules/kikiui-html/dist/components/modal.js" defer></script>

<button class="kiki-button" data-kiki-modal-open="example-modal">Open modal</button>
<dialog class="kiki-modal" id="example-modal" aria-labelledby="example-title">
  <div class="kiki-modal-header"><h2 class="kiki-modal-title" id="example-title">Hello</h2></div>
  <div class="kiki-modal-footer"><button class="kiki-button" data-kiki-modal-close>Close</button></div>
</dialog>

Each per-component script registers only its own key on window.Kiki (for example Kiki.modal), so you can mix and match. Some components build on others (Drawer and Command palette use Modal, for example). The registry entry for each component (registry/items/<name>.json) lists the exact stylesheets and scripts it needs, ready to copy.

JavaScript modules (bundlers: Vite, webpack, Rollup, esbuild…)

Import styles, then either use the auto-initialising component entries:

import "kikiui-html/tokens.css";
import "kikiui-html/components/modal.css";
import "kikiui-html/components/modal"; // side-effect entry: wires up [data-kiki-modal-*] markup

…or use the named exports, which have no side effects and can be tree-shaken, and call init() yourself:

import "kikiui-html/kiki.css";
import { Modal, Tabs, toast } from "kikiui-html";

Modal.init();
Tabs.init();
toast.success("Ready");

import { init } from "kikiui-html" initialises every module at once. All init() calls are idempotent and accept a root element for content you add later.

TypeScript

The runtime is plain JavaScript. Declarations ship in types/:

import { Modal, toast, type ToastOptions } from "kikiui-html";   // typed API + events
import type {} from "kikiui-html/global";                        // types for window.Kiki (script tags)

Package entry points

| Import | File | | --- | --- | | kikiui-html | ESM entry, named exports (dist/esm/index.js) | | kikiui-html/components/<name> | auto-initialising ESM entry for one component | | kikiui-html/components/<name>.css | one component's stylesheet | | kikiui-html/components/<name>.js | one component's classic <script> bundle | | kikiui-html/kiki.css, kiki.min.css (alias kikiui-html/css) | full stylesheet | | kikiui-html/kiki.js | full classic <script> bundle (window.Kiki) | | kikiui-html/tokens.css, tokens.json | design tokens | | kikiui-html/base.css | optional page base (element resets for pages you fully own) | | kikiui-html/utilities.css | small utility set (included in kiki.css) | | kikiui-html/fonts.css | optional Inter + JetBrains Mono webfonts (SIL OFL 1.1) | | kikiui-html/icons/* | sprite.svg, svg/<name>.svg, icons.json | | kikiui-html/registry.json | component registry | | kikiui-html/src/* | readable source, for teams that want to copy and own it |

Fonts are opt-in. Without fonts.css, components use the system UI font.

Theming and dark mode

Theming is pure CSS, driven by one attribute. No JavaScript is needed and nothing is rebuilt.

<html data-theme="light">   <!-- default -->
<html data-theme="dark">
<html data-theme="system">  <!-- follows the OS preference -->

<section data-theme="dark">…</section>  <!-- theme just a subtree -->

Every component reads semantic tokens (--kiki-canvas, --kiki-fg, --kiki-surface, --kiki-border, …), so light and dark switch together.

Your page background is yours. KIKI never styles <html> or <body>, so it can't restyle an existing site. On a page you own, either include the optional base.css, or add one rule so the page follows the theme too:

body { background: var(--kiki-canvas); color: var(--kiki-fg); }

The optional Theme behaviour persists the user's choice and powers declarative switcher buttons:

<button class="kiki-button" data-kiki-theme-set="dark">Dark</button>
<script>Kiki.theme.toggle();</script>

It stores the choice in localStorage["kiki-theme"]. To avoid a flash of the wrong theme, add this to <head>:

<script>try{var t=localStorage.getItem("kiki-theme");if(t)document.documentElement.dataset.theme=t}catch(e){}</script>

Density: data-density="compact" or "comfortable" on <html> or any container.

Customising: override tokens, for example :root { --kiki-radius-md: 4px; }. The full list is in dist/tokens/tokens.json.

Works alongside your existing CSS

  • Every class is prefixed kiki- (.kiki-button, .kiki-card, .kiki-modal). There are no generic class names.
  • Component stylesheets never style bare elements. base.css is the only file that does, and it is opt-in.
  • Every custom property and keyframe is prefixed --kiki- / kiki-.
  • The scripts create exactly one global, window.Kiki, and the ESM entry creates none.

An automated gate (npm run check) enforces these rules on every build.

Accessibility

  • Native elements first: <dialog> for Modal and Drawer, <details> for Accordion, a real <select> behind the enhanced Select, popover for floating layers.
  • Keyboard support follows the WAI-ARIA Authoring Practices:
    • roving focus and typeahead in menus, tabs and listboxes
    • arrow, Home and End keys, and Enter/Space activation
    • Esc to close, with a stack so only the topmost layer closes
  • Focus is trapped in modal layers and returned to the trigger when they close. Outside clicks dismiss menus and popovers.
  • ARIA roles and states are managed for you: aria-expanded, aria-controls, aria-selected and aria-activedescendant. Toasts use live regions, and tooltips are linked with aria-describedby.
  • Respects prefers-reduced-motion, prefers-reduced-transparency and forced-colors (Windows High Contrast). Touch targets are at least 24px on coarse pointers.
  • Tested with axe-core (no serious or critical violations) in light and dark themes, in Chromium, Firefox and WebKit.

Each component's page in the docs lists its keyboard map and accessibility notes.

Components (0.1.0)

| Category | Components | | --- | --- | | Actions | Button, Icon Button | | Forms | Field, Input, Textarea, Select (native + enhanced), Combobox, Checkbox, Radio, Switch | | Data display | Badge, Kbd, Card, Avatar, Table | | Feedback | Alert, Toast, Spinner & loaders, Skeleton, Progress | | Overlays | Tooltip, Dropdown menu (with submenus), Popover, Modal, Drawer, Command palette | | Navigation | Tabs, Accordion | | Foundations & behaviours | Tokens, Fonts, Icons (56), Glass material, Theme, Dismiss |

CSS only: Button, Icon Button, Field, Checkbox, Radio, Switch, Badge, Kbd, Card, Avatar, Alert, Spinner, Skeleton, Progress, Drawer (opened by the Modal script).

Needs a script: Tooltip, Dropdown, Popover, Modal, Command palette, Combobox, Toast, Tabs, Theme.

Works without JS, enhanced when the script is present: Select, Input, Textarea, Accordion, Table, Icons, Glass, closable Alert/Badge (Dismiss).

Browser support

Chrome / Edge 123+, Firefox 120+, Safari 17.5+. The library relies on light-dark(), :has(), the popover attribute and <dialog>.

Documentation

The docs site is built from this repository. Each component page has a live preview, the HTML, CSS and JS usage, installation, keyboard map, accessibility notes and API.

npm install
npm run build:all   # dist/ + site/
npm run serve       # http://localhost:4321/site/

site/architecture.html (source: docs/architecture.html) explains the CSS, JavaScript, package, GSAP and registry strategies.

Development

src/
  tokens/            colors · typography · spacing · radius · shadows · motion · z-index · breakpoints · theme · glass
  base/              base.css (optional page base) · utilities.css
  core/              dom · layers (Esc/outside stack) · position (flip/shift) · focus (roving, typeahead)
  icons/icons.js     icon set + render()
  components/<name>/ <name>.css · <name>.js · index.js (auto-init) · <name>.html (examples) · component.json · README.md
  index.js           ESM entry (named exports, side-effect free)
types/               TypeScript declarations
scripts/             build (esbuild) · build-docs · check (architecture gates) · serve
registry/            registry.json + items/<name>.json (generated from component.json)
docs/                docs site sources (assets, architecture page)
tests/unit|e2e|types node:test + Playwright + axe-core, tsc consumer checks
dist/ site/          build outputs (git-ignored)

component.json is the source of truth for each component; the registry and docs are generated from it.

| Script | What it does | | --- | --- | | npm run build | tokens, per-component CSS/JS, bundles, ESM mirror, icons, registry | | npm run docs | documentation site → site/ | | npm run check | scoping, token references, keyframes, raw colours, globals, registry & exports integrity, type check | | npm test | build + docs + check + unit tests | | npm run test:e2e | browser tests in Chromium (Edge/Chrome), Firefox and WebKit: behaviour & keyboard, console errors, axe (light/dark), overflow at 375/390/768/1024/1440, touch targets, mobile layout |

E2E needs a local Edge/Chrome (or KIKI_BROWSER=/path/to/chrome) plus npx playwright-core install firefox webkit. Limit engines with KIKI_ENGINES=chromium. WebKit is Playwright's build of Safari's engine, not Safari itself.

License

MIT, see LICENSE. Icon geometry is derived from Lucide (ISC), see THIRD_PARTY_NOTICES.md.