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

@iamtherealtim/lume-css

v2.1.0

Published

A minimal open-source CSS library for thoughtful interfaces.

Readme

Lume CSS

A minimal, open-source CSS library for thoughtful interfaces.

Lume ships a polished component set, design-token-based theming, dark mode, utility helpers, and practical docs/demo apps you can use as implementation references.

Live Links

  • Docs: https://iamtherealtim.github.io/lume-css/lume-docs.html
  • Admin demo: https://iamtherealtim.github.io/lume-css/admin-demo/dashboard.html

What’s Included

| File | What it is | | --- | --- | | dist/lume.css, dist/lume.min.css | The whole library in one stylesheet | | dist/reset.css | Global box-sizing reset and bare-element styles (body, a, code, pre, blockquote, kbd) | | dist/core.css | Design tokens, dark theme, typography and layout classes | | dist/components.css | All .lume-* components | | dist/utilities.css, dist/a11y.css, dist/responsive.css | Utility classes, focus and reduced-motion layer, breakpoints | | dist/extras.css | Opt-in decorative variants (gradient buttons). Not part of lume.css | | dist/lume.js | Optional runtime for modals, drawers, dropdowns, tabs, toasts and dismissible tags |

The docs, showcase and admin demo live in docs/ and are published at the live links above.

Quick Start

CDN

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@iamtherealtim/[email protected]/dist/lume.min.css" />
<script defer src="https://cdn.jsdelivr.net/npm/@iamtherealtim/[email protected]/dist/lume.js"></script>

Pin a version in production. Drop @2.1.0 to always get the latest release.

npm

npm install @iamtherealtim/lume-css
@import "@iamtherealtim/lume-css/lume.css";
// Side-effect import: runs the runtime and sets window.Lume
import "@iamtherealtim/lume-css/lume.js";

Package Contract

These paths are the public API of the package. Anything else inside the package may change without notice.

| Import path | Resolves to | | --- | --- | | @iamtherealtim/lume-css | dist/lume.css under the style condition, dist/lume.js otherwise | | @iamtherealtim/lume-css/lume.css | Full bundle | | @iamtherealtim/lume-css/lume.min.css | Full bundle, minified | | @iamtherealtim/lume-css/lume.js | Runtime | | @iamtherealtim/lume-css/{reset,core,components,utilities,a11y,responsive,extras}.css | Individual layers |

lume.js is a classic script, not an ES module. It has no exports. Loading it, by <script> tag or by side-effect import, sets window.Lume. The package declares sideEffects so bundlers keep both the CSS and the runtime.

Use Only Parts Of The Library

lume.css is the same as importing every layer in this order:

@import "@iamtherealtim/lume-css/reset.css";
@import "@iamtherealtim/lume-css/core.css";
@import "@iamtherealtim/lume-css/components.css";
@import "@iamtherealtim/lume-css/utilities.css";
@import "@iamtherealtim/lume-css/a11y.css";
@import "@iamtherealtim/lume-css/responsive.css";

To add Lume to an existing app without touching its base styles, leave out reset.css. Everything else only styles .lume-* classes, data-tooltip attributes and the data-theme / data-ui-init hooks on <html>. core.css is always required because it defines the tokens.

Gradient buttons (lume-btn-gradient-*) are kept out of the core bundle. Add them only where a page wants them:

@import "@iamtherealtim/lume-css/extras.css";

Fonts

Lume does not bundle fonts. The token stacks prefer Instrument Sans, Lora and JetBrains Mono, then fall back to system fonts, so Lume looks fine with nothing loaded. To match the docs, load them yourself, for example from Google Fonts:

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Lora:wght@600&family=JetBrains+Mono:wght@400;500&display=swap" />

To use your own fonts, override --lume-font-sans, --lume-font-serif and --lume-font-mono.

JavaScript Runtime

dist/lume.js is optional. Every component renders without it. It adds behaviour through data attributes and has no dependencies. Type declarations ship as dist/lume.d.ts.

| Attribute | Effect | | --- | --- | | data-lume-toggle + data-lume-target="#id" | Opens or closes a modal, drawer or dropdown. Use data-lume-toggle="dropdown" on menu triggers | | data-lume-open / data-lume-close | Opens or closes the target. A bare data-lume-close closes the dialog or menu it sits in | | data-lume-dismiss="toast" / "alert" | Removes the surrounding toast, or alert/callout | | data-lume-remove | Removes the surrounding tag, badge or chip, or the nearest ancestor matching its selector | | data-lume-autodismiss="6000" / "false" | Toast lifetime in ms (default 4500), or keep it. Hover pauses the remaining time | | data-lume-overlay, data-lume-panel | Point a drawer at its overlay, or a tab at its panel, when markup order can't |

An invalid selector in any of these attributes logs a console warning and is ignored. It never throws.

API

| Member | Returns | Notes | | --- | --- | --- | | Lume.open(target, trigger?) | void | target is a selector or element. Focus returns to trigger, or to whatever was focused before, on close | | Lume.close(target) | void | | | Lume.toggle(target, trigger?) | void | | | Lume.isOpen(target) | boolean | false if the target doesn't resolve | | Lume.initTabs(root?) | void | For tabs inserted after page load | | Lume.initToasts(root?) | void | Rarely needed; added toasts are picked up automatically | | Lume.dismissToast(toast) | void | | | Lume.version | string | |

Component contracts

| Component | lume.js provides | You provide | | --- | --- | --- | | Modal, drawer | Focus moved in and trapped; Escape closes the top-most dialog; focus restored; scroll locked without touching your body styles; role="dialog" and aria-modal added if missing; closed dialogs hidden from assistive tech | An accessible name: aria-labelledby or aria-label. The runtime warns when it's missing but never invents one | | Dropdown | The ARIA menu pattern: aria-haspopup, aria-expanded, Arrow/Home/End, Escape, item activation closes and restores focus, click or tab away closes | role="menu", role="menuitem", role="separator". Menus hold actions only | | Tabs | Roles, aria-selected, roving tabindex, aria-controls / aria-labelledby when ids exist, Arrow/Home/End, hidden inactive panels | Ids on tabs and panels; a label on the tab list | | Toast | Auto-dismiss, pause on hover, dismiss buttons | aria-live="polite" on the container (or role="alert"); labels on icon-only close buttons | | Tooltip | Nothing: data-tooltip is pure CSS | Treat it as a visual hint. Screen readers don't announce it, so never put information only there |

Full examples are in the docs.

Development

npm ci
npx playwright install chromium   # once, for the browser tests
npm run build      # src/ -> dist/ and docs/ runtime assets, stamps the version, prints sizes
npm test           # static checks: build output fresh, one version everywhere, classes defined, guards
npm run test:e2e   # Playwright: component behaviour + axe accessibility scans in both themes
npm run serve      # preview at http://localhost:4173/docs/

src/ holds every source file, including the runtime (src/lume.js) and its types. dist/ and the CSS/JS copies in docs/ are generated. Commit them anyway: the CDN serves dist/ and GitHub Pages serves docs/. CI fails if they don't match a fresh build, or if any test fails.

The version lives only in package.json. The build stamps it into every CSS banner and into Lume.version.

No-Flicker Startup (Recommended)

Use this pattern in your app shell for stable first paint (theme + icon hydration):

<script>
  document.documentElement.setAttribute('data-ui-init', 'pending');
  try {
    const savedTheme = localStorage.getItem('lume-theme');
    if (savedTheme) document.documentElement.setAttribute('data-theme', savedTheme);
  } catch (_) {}
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@iamtherealtim/[email protected]/dist/lume.min.css" />
<script defer src="https://unpkg.com/[email protected]/dist/umd/lucide.min.js"></script>

The matching CSS guard (html[data-ui-init="pending"] body { visibility: hidden; }) is built into lume.css, so you only need to remove the attribute once your own hydration is done:

document.documentElement.removeAttribute('data-ui-init');

If lume.js is loaded it also clears the attribute shortly after window.load as a safety net, so a page can never stay blank.

Core + extended patterns include:

  • Buttons, Forms, Cards, Badges, Alerts, Tables
  • Modal, Tooltip, Tabs, Accordion, Dropdown
  • Progress, Avatar, Toast, Breadcrumb, Pagination, Skeleton
  • Callout, List Group, Stat, Empty State, Stepper, Drawer, Kbd

Browser Support

Lume uses color-mix(), :focus-visible, inset, aspect-ratio and :not() selector lists. That means Chrome/Edge 111+, Firefox 113+ and Safari 16.4+. There are no polyfills or fallbacks for older browsers.

Accessibility & UX

  • Focus-visible outlines for interactive controls
  • Reduced-motion handling for animations
  • Dark mode via html[data-theme="dark"] with a real elevation scale: page, recessed surface, raised card, floating overlay each get their own shade
  • --lume-on-accent keeps text on solid accent/danger fills white in both themes
  • Every text token meets WCAG AA (4.5:1) on every surface and tint in both themes, enforced by axe scans in CI
  • Focus rings derive from --lume-accent through --lume-focus-ring, so brand overrides carry through
  • First-paint stability pattern documented in the docs

Repo Structure

.
├── src/                 source of truth: CSS layers + runtime (lume.js)
├── dist/                generated, published to npm
├── docs/                GitHub Pages site: docs, showcase, admin demo, templates
├── scripts/
│   ├── build.mjs        builds dist/ and docs/ runtime assets
│   ├── check.mjs        static checks (npm test)
│   └── serve.mjs        static server for preview and tests
├── tests/               Playwright fixture, behaviour specs, axe specs
├── notes/               planning notes, not part of the library
└── .github/workflows/   CI

License

MIT — see LICENSE.

Contributing

See CONTRIBUTING.md for contribution workflow and PR checklist.