liquid-glass-cli
v1.1.4
Published
A React implementation of Apple's iOS 26 Liquid Glass material — added to your project shadcn style, copied in rather than installed as a dependency.
Maintainers
Readme
liquid-glass-cli
A React take on Liquid Glass, the translucent material Apple introduced in iOS 26 — real refraction, chromatic dispersion, and specular light, rendered on the web.
Add the component to your project shadcn style: the code is copied into your codebase, so you own it, can read it, and can change it. Nothing is added to your dependencies except the two tiny utilities the component itself imports.
npx liquid-glass-cli add liquid-glassWhat it does
Running add liquid-glass will:
- Write
components/ui/liquid-glass.tsx(orsrc/components/ui/...when your project has asrcdirectory) - Write
lib/utils.tswith thecnhelper, if it isn't there already - Install
clsxandtailwind-merge
Existing files are never overwritten silently — pass --overwrite when you want to replace them.
Requirements
- Node.js 18 or newer
- A React project with Tailwind CSS
- A
@/*path alias pointing at your source root
Commands
| Command | Description |
|---|---|
| add <component> | Add a component to your project |
| list | List every component available in the registry |
Options for add
| Option | Description |
|---|---|
| --overwrite | Replace files that already exist |
| --skip-install | Don't install npm dependencies automatically |
The component
<LiquidGlass> wraps any content in a real refracting glass surface.
The panel is a squircle: the silhouette, the rim stroke, and the displacement map are all sampled off the same superellipse, so they never disagree at the corners. The bevel is modelled as a quarter-round of glass and its displacement map comes from Snell's law — every pixel inside the edge band stores the shape's outward normal scaled by how hard a ray bends at that point, so the backdrop is pulled around the corners along the true surface direction rather than along the x and y axes. The bend climbs steeply over the last few pixels of the rim, and that concentration is what reads as liquid.
Layered on top: a frosted tint, a specular ring that flares where the bevel faces the light and again — more faintly — on the far arc where the light leaves the glass, a crisp rim stroke masked to the outline, and a drop shadow that lifts the panel off its backdrop. Each color channel is displaced by a slightly different amount to produce chromatic dispersion. The displacement map is rebuilt through a ResizeObserver, so the effect stays correct at any size.
Corner shape. cornerSmoothing maps straight onto CSS corner-shape: superellipse(k): 0 is round, 100 is squircle, the corner Apple draws. Where the browser supports corner-shape, the panel is cut with border-radius and corner-shape rather than a clip-path — which matters, because a backdrop-filter is clipped by the border box and its corners, and a clip-path never reaches it. With it, the refracted backdrop, the shadows, the rim stroke, and the silhouette all land on one outline. Without it the component squares the box and clips with a path(), then masks the two filtered layers with the filled shape — a mask, unlike a clip path, does clip a backdrop — so the frost keeps following the corners in Safari and on iOS. The shadows are shaped by a radius rather than clipped by a path, so there they take the circular radius that crosses the superellipse at its own diagonal point, hugging the squircle instead of pinching inside it.
import { LiquidGlass } from "@/components/ui/liquid-glass";
export function Card() {
return (
<LiquidGlass
cornerRadius={24}
cornerSmoothing={60}
tint="rgba(17, 21, 27, 0.6)"
className="p-6"
>
<h2 className="text-white">Liquid Glass</h2>
</LiquidGlass>
);
}Props
Besides children, className, and style:
| Prop | Type | Default | Description |
|---|---|---|---|
| tint | string | "rgba(17, 21, 27, 0.8)" | Fill color layered over the refracted backdrop. Any CSS color. |
| cornerRadius | number | 48 | Corner radius in pixels. |
| cornerSmoothing | number | 32 | Continuity of the corner curve (0–100). 0 is a plain circular arc, 100 the squircle Apple draws — the same span CSS walks from corner-shape: round to corner-shape: squircle. |
| refraction | number | 100 | How strongly the backdrop bends at the edges (0–100). |
| depth | number | 85 | Thickness of the refracting edge band — the perceived glass depth (0–100). |
| dispersion | number | 100 | Chromatic aberration: how far the red and blue channels split (0–100). |
| frost | number | 3 | Backdrop blur in pixels. |
| splay | number | 38 | How far the bend spreads inward from the rim (0–100). 0 is a crisp lens, 100 a wide swell. |
| lightAngle | number | 45 | Direction the specular highlight comes from, in degrees. |
| lightIntensity | number | 38 | Strength of the specular highlight and the rim stroke (0–100). |
| borderWidth | number | 1 | Width of the inside rim stroke in pixels. Use 0 to drop the stroke layer and draw your own border. |
| elevation | number | 22 | Height of the drop shadow cast behind the panel (0–100). Use 0 to remove the shadow layer. |
| layerClassName | string | — | Applied to each effect layer instead of the container — use it to mask the glass. |
Masking: apply masks through
layerClassName, not on the container. Anything that forms a backdrop root on the container (isolation,filter,opacity,mask,contain: paint) makes the layers sample an empty backdrop and blanks the effect out.
Browser support
Chromium renders the full effect. Firefox and Safari treat backdrop-filter: url() as invalid, so the refraction layer stays inert there and the frost, tint, specular ring, and rim stroke carry the look on their own — it degrades gracefully rather than breaking.
The squircle corners ride on CSS corner-shape, which Chromium ships and the others don't yet. The component feature-detects it at runtime and falls back to a path() clip for the silhouette plus a shape-filled mask on the refraction and frost layers — the one clip WebKit applies to a backdrop — so the panel and the blur behind it both keep the squircle either way. The bevel shading and the drop shadow are inset and outer shadows, which a radius forms rather than clips; in the fallback they take the circular radius matched to the superellipse's diagonal, so they stay tight against the outline instead of leaving a gap at the corners.
Author
Aryan Kholghi
- GitHub — @aryankholqi
- LinkedIn — aryan-kholqi
License
MIT © Aryan Kholghi
This project is an independent, unaffiliated reinterpretation of the Liquid Glass design language for the web. Apple and iOS are trademarks of Apple Inc.
