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

liquid-glass-js

v0.1.0

Published

Cross-browser liquid-glass refraction (Chrome / Safari / Firefox). Real optical displacement with magnification, chromatic aberration and a normal-based specular highlight. Zero dependencies. JS class + <liquid-glass> web component.

Readme

liquid-glass-js

Cross-browser liquid-glass refraction for the web — real optical displacement (not a blur fake), with convex magnification, chromatic aberration and a normal-based specular highlight. Zero dependencies. Ships as a JavaScript class and a <liquid-glass> web component.

npm license size

  • 🔬 Real refraction via SVG feDisplacementMap driven by a height-field optical model — convex surfaces magnify, concave shrink.
  • 🌈 Chromatic aberration + specular highlight computed from the surface normal.
  • 🧭 Works in Chrome, Safari and Firefox. Most demos out there are Chromium-only (they reference an SVG filter from backdrop-filter); this one refracts a clone of the background instead, so it runs everywhere.
  • 🪶 ~13 kB min, zero dependencies, ESM / CJS / UMD + TypeScript types.
  • 🖱️ Draggable, fully runtime-configurable.

Live demo: open index.html (full playground) or example.html (one-tag web component) — or visit the GitHub Pages demo.


Install

npm install liquid-glass-js

Or via CDN (no build step):

<script src="https://unpkg.com/liquid-glass-js"></script>

Quick start

A. JavaScript class

import LiquidGlass from 'liquid-glass-js';

const glass = new LiquidGlass({
  background: document.querySelector('#scene'), // element to refract (it gets cloned)
  width: 360, height: 220, radius: 48,
  scale: 46, chroma: 0.1, tint: 0,
});

glass.set({ scale: 60 });  // update params
glass.moveTo(120, 80);     // move it
glass.refresh();           // re-clone after the background changes
glass.destroy();           // tear down

B. Web component

<div id="scene"><!-- the background to refract --></div>

<liquid-glass background="#scene" width="360" height="220"
              scale="46" chroma="0.1" tint="0"></liquid-glass>

<script src="https://unpkg.com/liquid-glass-js"></script>

Importing the module (or the UMD script) registers the <liquid-glass> element automatically.


How it works

The glass element does not blur a backdrop — it bends the actual pixels. A small displacement map is generated on a canvas from a rounded-rectangle SDF and a thickness profile ((1 - (1-t)^k)^(1/k), a circle→squircle curve). The map's R/G channels encode per-pixel displacement; an SVG filter (feImagefeDisplacementMap) applies it. Displacement points inward, so a convex bezel converges rays and magnifies, exactly like a real lens. Three passes at slightly different scales give chromatic aberration, and a second canvas encodes a specular highlight from the surface normal.

To stay cross-browser it uses clone mode: the background element you point it at is cloned into a small, clipped overlay that the filter is applied to (Safari/Firefox don't support referencing an SVG filter from backdrop-filter). The clone is kept pixel-aligned with the real background.


API

new LiquidGlass(options)

options is the parameter table below plus:

| option | type | default | description | | --- | --- | --- | --- | | background | Element \| null | null | Element to refract. It is cloned. | | draggable | boolean | true | Allow pointer dragging. | | zIndex | number | 100 | z-index of the lens layer (glass sits at z+1). | | x, y | number | centered | Initial screen position of the glass top-left. |

Parameters

| param | range | default | description | | --- | --- | --- | --- | | width / height | px | 360 / 220 | Glass size. | | radius | px | 48 | Corner radius. | | scale | 0..90 | 46 | Refraction strength (max edge displacement). | | depth | px | 40 | Bezel width — how far the curve reaches inward. Large ≈ full dome. | | curvature | 1.2..6 | 2.2 | Profile exponent: ~2 spherical, ~4 squircle. | | convexity | -1..1 | 1 | +1 convex (magnify), 0 flat, -1 concave (shrink). | | chroma | 0..0.6 | 0.1 | Chromatic aberration. | | blur | px | 0 | Frost / backdrop blur (0 = clear). | | glow | 0..1 | 0.18 | Glow strength. | | edge | 0..1 | 0.7 | Specular highlight strength. | | specAngle | 0..360 | 135 | Specular light angle. | | tint | 0..1 | 0 | Tint opacity. | | tintColor | CSS color | #ffffff | Tint color. |

Methods

| method | description | | --- | --- | | set(partial) | Update one or more parameters (rebuilds maps only when needed). | | get(key?) | Get one parameter, or a copy of all. | | moveTo(x, y) | Move the glass (screen coords of its top-left). | | setBackground(el) | Swap the refracted element. | | refresh() | Re-clone the background and rebuild (call after it changes). | | destroy() | Remove all DOM, filters and listeners. |

Web component attributes

Every parameter is an attribute (camelCase → kebab-case, e.g. spec-angle, tint-color), plus background (a CSS selector), draggable, z-index, x, y. Attributes are reactive.


Framework usage

Because it's a standard custom element, <liquid-glass> works in Vue, Svelte and Angular out of the box. In React (< 19) set attributes as strings, or just use the class in an effect:

useEffect(() => {
  const g = new LiquidGlass({ background: ref.current, scale: 46 });
  return () => g.destroy();
}, []);

Browser support & caveats

  • Needs SVG filters, pointer events, clip-path and custom elements — all evergreen browsers. tint > 0 uses color-mix() (Chrome 111+, Safari 16.2+, Firefox 113+); tint: 0 (the default) avoids it.
  • Clone mode refracts a clone of the background, so the background must be clonable DOM/CSS (a known element). It is not a drop-in over arbitrary live app UI — for that you'd want a backdrop-filter mode (Chromium-only), which is not included here by design.
  • The clone is a static snapshot. If the background animates or changes, call refresh().
  • The clone keeps element ids so id-based styles survive; this means ids are briefly duplicated in the DOM (the clone is aria-hidden; your own getElementById/querySelector still return the original).
  • No cross-origin canvas reads are performed (the maps are procedural), so cross-origin images in the background are fine.

Build from source

npm install
npm run build   # -> dist/ (esm, cjs, umd, minified, sourcemaps, d.ts)

License

MIT © Eamon Liu