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 🙏

© 2025 – Pkg Stats / Ryan Hefner

liquid-glass-component-kit

v1.0.3

Published

Apple-inspired liquid glass morphism toolkit - Create stunning glassmorphism UI components with vanilla JavaScript

Readme

Liquid Glass Component Kit

🚀 View Live Demo | 📦 npm Package

🍎 Apple-inspired liquid glass morphism toolkit for creating stunning glassmorphism UI components.

Simply wrap buttons, images, form elements etc. Ensure they are positioned over a BG image, and voila!

A production-ready vanilla JavaScript library that brings beautiful liquid-glass effects to any HTML element with Apple-style polish and performance.

Features complete glassmorphism effects including specular highlights, backdrop blur, color filters, SVG refraction, edge distortion, and chromatic aberration - inspired by Apple's design language and modern glass morphism trends.

Credit:

Wouldn’t have been possible without the incredible work documented here: https://atlaspuplabs.com/blog/liquid-glass-but-in-css

✨ Features

  • 🎯 Simple Liquid-Glass API - Pure functions, no classes, clean liquid-glass integration
  • 🔧 Zero Dependencies - The vanilla JavaScript version doesnt need any.
  • ⚛️ React Support - Set up with React too if thats how you roll
  • 📱 Cross-browser Liquid-Glass - Progressive enhancement with liquid-glass fallbacks
  • Optimized Liquid-Glass Effects - Fast SVG filters and GPU-accelerated liquid-glass
  • 🎨 Customizable Liquid-Glass - Multiple liquid-glass intensity levels (subtle, normal, strong)
  • 🖼️ Universal Liquid-Glass - Apply liquid-glass to buttons, inputs, images, cards, any element

Installation

For Vanilla JavaScript Projects

npm install liquid-glass-component-kit

For React Projects

npm install liquid-glass-component-kit react

Note: React is an optional peer dependency. Vanilla JS users get zero React bloat - the React hooks are in a separate entry point (/react) that's only loaded when explicitly imported.

Importing Styles

The package includes CSS styles that need to be imported at root for the liquid glass effects to work. You can import them in several ways:

Using CSS Import

@import 'liquid-glass-component-kit/styles';

Using JavaScript Import

import 'liquid-glass-component-kit/styles';

Quick Start

💡 Tip: Try the interactive demo to see all effects in action!

Vanilla JavaScript

import { applyLiquidGlass } from 'liquid-glass-component-kit';

// Get element and apply liquid-glass effect (applies immediately)
const button = document.querySelector('#myButton');
const effect = applyLiquidGlass(button);

// Apply with custom intensity (applies immediately) 
const strongEffect = applyLiquidGlass(button, { intensity: 'strong' });

// Remove effects when done
effect.remove();        // removes first effect
strongEffect.remove();  // removes strong effect

React

import { useLiquidGlass } from 'liquid-glass-component-kit/react';

function MyButton() {
  const [glassRef] = useLiquidGlass({ intensity: 'strong' });
  return <button ref={glassRef}>Click me</button>;
}

Usage

Basic Usage

import { applyLiquidGlass } from 'liquid-glass-component-kit';

// Apply default liquid-glass effect (applies immediately)
const element = document.querySelector('.my-element');
const effect = applyLiquidGlass(element);

// The function returns an effect object
// Call remove() when you want to remove the liquid-glass effect
effect.remove();

With Options

// Liquid-glass with custom intensity (applies immediately)
const applyEffect = applyLiquidGlass(element, {
  intensity: 'strong'     // liquid-glass intensity: 'subtle' | 'normal' | 'strong'
});

Multiple Elements

import { applyToMultiple } from 'liquid-glass-component-kit';

// Apply to multiple elements at once
const buttons = document.querySelectorAll('.liquid-buttons');
const buttonEffects = applyToMultiple(buttons, { 
  intensity: 'subtle' 
});

// Cleanup all
buttonEffects.forEach(effect => effect.remove());

Global Cleanup

import { cleanupAll } from 'liquid-glass-component-kit';

// Remove all liquid glass effects and SVG filters
cleanupAll();

API Reference

applyLiquidGlass(element, options?)

Applies liquid glass effect to a single element.

Parameters:

  • element (HTMLElement) - Target element
  • options (Object, optional) - Configuration options
    • intensity (string) - Effect intensity: 'subtle', 'normal', 'strong' (default: 'normal')

Returns: Object - Effect object with remove() method

applyToMultiple(elements, options?)

Applies liquid glass effect to multiple elements.

Parameters:

  • elements (NodeList | Array) - Target elements
  • options (Object, optional) - Same as applyLiquidGlass

Returns: Array of effect objects with remove() methods

cleanupAll()

Removes all liquid glass effects and cleans up SVG filters.

Effects Included

Core Glass Effects (All Browsers)

  • Specular Highlights - Multi-layered inset shadows for realistic depth
  • Backdrop Blur - Gaussian blur with progressive enhancement
  • Color Filters - Saturation and contrast adjustments for glass tinting
  • Glass Depth - Box shadows and background transparency
  • Gradient Borders - Subtle light reflections on edges

Enhanced Effects (Desktop + Android)

  • SVG Refraction - Advanced refraction using SVG displacement filters
  • Edge Distortion - Radial distortion mapping with feTurbulence
  • Ripple Distortion - Turbulence-based organic glass distortion
  • Chromatic Aberration - RGB channel separation for realistic glass behavior

All effects are applied using progressive enhancement, ensuring every user gets a beautiful glass experience appropriate for their device capabilities.

Browser Support

Desktop Browsers

  • Chrome/Edge 76+ - Full support with all effects including SVG distortion
  • Firefox 103+ - Full support with all effects including SVG distortion
  • Safari 14+ - Full support with all effects including SVG distortion

Mobile Browsers

  • iOS Safari/Chrome - Glass effects with blur and saturation (no SVG distortion)
  • Android Chrome - Full support with all effects including SVG distortion
  • Older browsers - Graceful fallback to basic glass styling

Progressive Enhancement

The library uses CSS @supports queries to provide:

  • Base layer: Beautiful glass effects (blur, saturation, highlights) that work everywhere
  • Enhanced layer: Advanced SVG distortion filters on supported browsers
  • Fallback layer: Semi-transparent styling when backdrop-filter isn't supported

Technical Note: iOS Safari and Chrome don't support backdrop-filter with url() SVG filters. The library automatically detects this limitation using CSS @supports queries and provides appropriate fallbacks, ensuring consistent visual quality across all platforms without requiring JavaScript device detection.

SSR Compatibility

The library is fully compatible with Server-Side Rendering frameworks like Next.js, Remix, Nuxt, and others:

How It Works

  • Server: Renders clean HTML with base glass effects (no SVG distortion)
  • Client: Detects browser capabilities and adds SVG enhancement after hydration
  • No Hydration Mismatches: HTML structure remains identical between server and client

Technical Implementation

The library uses CSS custom properties for progressive enhancement:

// Automatically sets on first effect application
document.documentElement.style.setProperty('--svg-filters-enabled', '1');
/* Base effects - work everywhere */
.liquid-glass {
  backdrop-filter: blur(2.5px) saturate(120%) contrast(120%) brightness(98%);
}

/* Enhanced effects - only when capability is detected */
@supports (backdrop-filter: url(#test)) {
  html[style*="--svg-filters-enabled: 1"] .liquid-glass {
    backdrop-filter: blur(2.5px) saturate(120%) url(#liquidGlassFilter);
  }
}

Benefits

  • Zero hydration issues - Server and client HTML structure match
  • Progressive enhancement - Base effects work everywhere, SVG distortion on capable browsers
  • Responsive - Works at any browser size, responds to window resizing
  • Framework agnostic - Works with any SSR framework

SVG Filter Compatibility

The Mobile SVG Filter Issue

During development, we discovered that mobile browsers (particularly iOS Safari and Chrome) report support for backdrop-filter: url(#filter) via CSS @supports queries, but the SVG filters don't actually work and can break the entire backdrop-filter declaration.

Our Solution

The library uses a sophisticated detection approach:

/* Enhanced effects only for desktop browsers */
@supports (backdrop-filter: url(#test)) and (hover: hover) and (pointer: fine) {
  /* SVG distortion filters applied here */
}

This ensures:

  • Desktop browsers: Get full SVG distortion effects
  • Mobile browsers: Get reliable backdrop-filter effects without problematic SVG URLs
  • Older browsers: Get graceful fallbacks

Why This Matters

Without this detection, mobile users would see no glass effects at all because the SVG filter URL breaks the entire backdrop-filter property. Our approach guarantees that every user gets beautiful glass effects appropriate for their device.

Performance

The component is optimized for performance:

  • SVG filters are shared across instances
  • GPU-accelerated CSS effects
  • Minimal DOM manipulation
  • Efficient cleanup functions

Examples

Button with Liquid Glass

const button = document.querySelector('.cta-button');
applyLiquidGlass(button, { intensity: 'strong' });

Form Inputs

const inputs = document.querySelectorAll('input, textarea');
applyToMultiple(inputs, { intensity: 'subtle' });

Image Gallery

const images = document.querySelectorAll('.gallery img');
applyToMultiple(images, { intensity: 'subtle' });

Cards/Containers

const cards = document.querySelectorAll('.card');
applyToMultiple(cards, { intensity: 'normal' });

React Usage

Import Styles

First, import the required CSS styles:

import 'liquid-glass-component-kit/styles';

Basic React Hook

import { useLiquidGlass } from 'liquid-glass-component-kit/react';

function GlassButton({ children, intensity = 'normal' }) {
  const [ref] = useLiquidGlass({ intensity });
  return <button ref={ref}>{children}</button>;
}

React Hook with Controls

import { useLiquidGlass } from 'liquid-glass-component-kit/react';

function InteractiveCard() {
  const [ref, { removeEffect, reapplyEffect }] = useLiquidGlass({ 
    intensity: 'strong' 
  });
  
  return (
    <div ref={ref} className="card">
      <h3>Glass Card</h3>
      <button onClick={removeEffect}>Remove Effect</button>
      <button onClick={reapplyEffect}>Reapply Effect</button>
    </div>
  );
}

Multiple Elements Hook

import { useLiquidGlassMultiple } from 'liquid-glass-component-kit/react';
import { useRef, useEffect } from 'react';

function GlassGallery() {
  const imagesRef = useRef([]);
  const { applyToElements } = useLiquidGlassMultiple({ intensity: 'subtle' });
  
  useEffect(() => {
    applyToElements(imagesRef.current);
  }, [applyToElements]);
  
  return (
    <div>
      {[1, 2, 3].map(i => (
        <img 
          key={i}
          ref={el => imagesRef.current[i-1] = el}
          src={`image${i}.jpg`}
          alt={`Glass effect ${i}`}
        />
      ))}
    </div>
  );
}

TypeScript Support

import { useLiquidGlass, LiquidGlassOptions } from 'liquid-glass-component-kit/react';

interface Props {
  intensity?: LiquidGlassOptions['intensity'];
}

function TypedGlassComponent({ intensity }: Props) {
  const [ref] = useLiquidGlass({ intensity });
  return <div ref={ref}>TypeScript glass effect</div>;
}

Development

# Install dependencies
npm install

# Start development server with demo
npm run dev

# Run tests
npm test

# Build for production
npm run build

License

MIT License - see LICENSE file for details

Credits

Based on the liquid glass CSS technique by Atlas Pup Labs.