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

leicht

v0.2.0

Published

A tiny classless-first CSS library in modern CSS: cascade layers, light-dark(), squircles, glass and liquid refraction. Link one file, write ordinary HTML.

Readme

leicht

npm gzip size license

A tiny classless-first CSS library, written in modern CSS. Link one file, write ordinary HTML, and it's styled. 6.8 kB gzipped, no build step, no dependencies.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/leicht.min.css">
npm i leicht

Docs and live demos →

Screenshots

Plain HTML, no classes — light and dark follow the OS:

| | | |---|---| | Light mode | Dark mode |

Every variant is a repointed variable, so they combine, and the markup underneath each demo is generated from the demo itself:

Button variants and the markup that produced them

Six skins in an optional 1.6 kB file — identical markup in every panel, only data-skin changes:

The six skins side by side

.liquid stacks refraction, tint and a specular rim on pseudo-elements, with live controls in the docs:

The liquid glass playground

What you get without writing a single class

Headings, links, lists, tables, <code>/<pre>, <blockquote>, <details>, forms and fieldsets, <nav>, <article> as a card, <dialog> as a modal, [popover] menus anchored to their button, popover="hint" tooltips, <progress>, <meter>, and a checkbox with role="switch" as a real toggle.

And a whole application, still without a class

Each of these keys off the markup that already makes it accessible, so you write the correct HTML and the styling follows:

| Markup | What you get | |---|---| | <aside> as a child of <body> | An app shell: sidebar column plus content. Add popover to the <aside> and a popovertarget button, and below 60rem it becomes an off-canvas drawer the browser opens, light-dismisses and animates — no JavaScript. | | <figure> around a <table> | A data table: framed, horizontally scrolling inside its own box instead of pushing the page sideways, with <figcaption> as the caption row. Set --l-table-max to cap the height and the <thead> sticks. | | <aside> <nav> | A vertical sidebar nav, with [aria-current] marking the page. | | [role=tablist] + [role=tab][aria-selected] | Tabs with an indicator. | | <output> as a child of <body> | A toast stack, pinned to the corner. It is already a live region. | | [aria-busy=true] | A shimmering skeleton — or, on a <button>, a spinner and a disabled state. | | <nav aria-label="…"> around an <ol> | Pagination, with [aria-current] marking the page. | | <dl> | A two-column key/value grid: invoice totals, metadata, spec sheets. | | <td class="num"> or <td><data value="…"> | A right-aligned numeric cell. |

The acceptance test is a full billing console — shell, data table, tabs, row menus, a modal, a filter panel, toasts, a settings form — written with no custom CSS at all. A test asserts it stays that way.

And a few classes when you need them

| | | |---|---| | .row / .col-1….col-12 | 12-column grid on CSS grid; a bare .row splits evenly | | .card | what <article> already gets, on anything | | .button, .secondary, .outline, .ghost, .error, .success | variants repoint variables, so they combine | | .alert | callout; takes the same variants | | .group | join buttons into one segmented bar | | .tag, .carousel, .glass, .liquid | badge, scroll-snap list with dots, and the two glass materials | | .warning, .neutral | the third and fourth semantic states, alongside .error and .success | | .sm, .lg | control sizes. They set only font-size, because control padding is em | | .field | a row an <input> can share with a $ prefix, a search icon or a unit suffix | | .avatar (takes --size), .dot | initials or an image in a round box, and a status dot that inherits the variant colour | | .flex, .stack, .between, .end, .truncate, .text-center, .text-muted, .hide-sm, .sr-only, .container | utilities |

Theming

Everything is a token. Your CSS sits outside leicht's cascade layers, so it always wins — you never need !important.

:root {
  --l-primary: #0a66c2;   /* a brand colour; everything else mixes from it */
  --l-hue: 150;           /* or re-tint neutrals and accent together */
  --l-radius: .25rem;
  --l-corner: round;      /* opt out of squircles */
  --l-space: .75rem;      /* one knob for density: every component tightens */
}

--l-space is the density control. Layout spacing derives from it through --l-space-xs/sm/md/lg/xl, so changing it compacts or loosens cards, dialogs, alerts, the sidebar and the toast stack together. Component interiors — buttons, tags, table cells, form controls — stay in em on purpose, so they scale with their own font size instead. That is what lets .sm and .lg resize a whole control with one declaration.

The other application-layer tokens: --l-aside (sidebar width, 15rem), --l-table-max (table height cap, none), --l-warning (the third state), --l-focus (the focus ring, so a skin can re-point it), and --l-width: none to opt a page out of the 72rem measure entirely.

Because the palette is OKLCH and holds lightness fixed, changing --l-hue measures the same contrast at every hue — 4.86:1 against the page. A raw brand colour is the one that can fail: check it if it's light.

Dark mode follows the OS. Force it with <html data-theme="dark">.

Skins

leicht-themes.css (1.6 kB gzipped, optional) adds six looks as token blocks — cyber, terminal, brutal, nord, mono, sunset. They compose with light/dark.

<link rel="stylesheet" href="leicht.min.css">
<link rel="stylesheet" href="leicht-themes.min.css">
<html data-skin="terminal" data-theme="dark">

Modern CSS, degrading quietly

The baseline is cascade layers, native nesting, light-dark(), color-mix(), :has() and container queries. On top of that, features are used as progressive enhancement and fall back to the plain look where they're missing: squircle corners, border-shape, a specular rim painted with background-clip: border-area, liquid-glass refraction from a data-URI SVG filter, anchor positioning, customizable <select>, scroll-driven animations, @container scroll-state, ::scroll-marker, the CSS Custom Highlight API, typed attr() and contrast-color().

Also included, because nobody ships them: a real print stylesheet, forced-colors and reduced-transparency support, a skip link that needs no class, and RTL through logical properties.

Build

No build is needed to use leicht. To change it:

npm run build     # inlines src/ imports, minifies, checks a gzip budget
npm run dev       # rebuild on change

The build is plain Node with no dependencies. It deliberately uses no CSS parser — parsers lag the syntax this library is built on.

License

MIT © Mojtaba Beheshti