LeonardSEO/liquid-glass-react

Real Apple-style "Liquid Glass" edge refraction for React/Next.js using a single SVG feDisplacementMap filter | no WebGL, no canvas rendering, ~5KB

TypeScript

7

10 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

I built a React liquid glass component that refracts the background at the edges. No WebGL (r/reactjs)

There are already plenty of liquid glass libraries. What I wanted was a clear centre with a curved rim that magnifies and stretches the content behind it. So I modelled the rim as a lens. The component uses Snell’s law to calculate refraction, generates an SVG displacement map for each element’s…

0

Oct 12, 2026

README

Liquid Glass for React: glass pills and orbs refracting a ribbon wallpaper

Liquid Glass for React

Apple's iOS 26 / macOS 26 Liquid Glass material for the web.
Physically based refraction, a specular rim and touch-reactive glass.
No WebGL, no canvas snapshots, no per-frame JavaScript.

npm bundle size MIT license React 18+ Next.js ready Zero dependencies Full effect in Chromium

Try the live demo — no installation needed
https://leonardseo.github.io/liquid-glass-react/


Most "liquid glass" CSS on the web is backdrop-filter: blur() in a rounded box. Real Liquid Glass bends light: the centre stays clear, while the curved rim magnifies and stretches whatever is behind it and catches a bright edge highlight.

This library models that rim as an actual lens. It traces light through it with Snell's law, writes the result into an SVG displacement map sized to each element, and lets the browser apply it in its normal backdrop-filter pass.

npm install @vepando/liquid-glass-react
import "@vepando/liquid-glass-react/style.css"
import { LiquidGlass } from "@vepando/liquid-glass-react"

<LiquidGlass radius={999} interactive style={{ height: 64 }}>
  <nav>…</nav>
</LiquidGlass>

Music app tab bar with sliding glass droplet and mini player; dark Siri-style glass panel

Contents

Features

  • Physically based refraction. The rim is a convex squircle bezel. Rays are refracted at n = 1.5 and traced down to the content beneath. The centre stays undistorted and the rim magnifies.
  • Pixel-exact maps per element. Each map is generated for the element's measured size and regenerated on resize, so the bend sits right on the curve whatever the shape.
  • Clear rim, tinted centre. The tint fades out across the bezel, so the refracted backdrop shows bright at the edge, as in Apple's glass.
  • Angle-dependent specular. A crisp edge line plus a soft inner glow that follows a configurable light direction.
  • Chromatic dispersion. R, G and B bend by slightly different amounts for a faint colour fringe on high-contrast edges.
  • Touch interaction. interactive adds a springy press-to-grow and a glow from the touch point.
  • Light and dark tints, or any CSS colour.
  • SSR safe. A frosted fallback renders on the server and upgrades on mount, without hydration mismatches.
  • Cached maps. Identical controls share maps. New sizes and optical settings generate maps synchronously; large panels and continuous resizing can be expensive. SVG backdrop rendering still costs work every frame, especially with dispersion. Many-element rendering has not been benchmarked across browsers and devices.
  • Zero dependencies. React 18+ is the only peer dependency. ESM + CJS + TypeScript types, about 5 KB gzipped.

Install

npm install @vepando/liquid-glass-react
# or: pnpm add @vepando/liquid-glass-react · yarn add @vepando/liquid-glass-react · bun add @vepando/liquid-glass-react

Import the stylesheet once, e.g. in your root layout or entry file:

import "@vepando/liquid-glass-react/style.css"

Then use the component anywhere:

import { LiquidGlass } from "@vepando/liquid-glass-react"

Next.js App Router: the bundle is already marked "use client", so you can render <LiquidGlass> straight from a server component. Put the CSS import in app/layout.tsx. Tested with next build and React 18/19 SSR.

Prefer to own the code? The source is three files in src/. The copy-paste version in skills/liquid-glass/assets/ works without the package.

Usage

Floating navbar

<LiquidGlass radius={999} className="h-16 w-full max-w-3xl">
  <nav className="h-full flex items-center justify-between px-6">…</nav>
</LiquidGlass>

Round icon button

<LiquidGlass radius={999} interactive className="h-16 w-16">
  <button type="button" aria-label="Search" onClick={openSearch}
    className="h-full w-full rounded-full border-0 bg-transparent cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2">
    <SearchIcon aria-hidden="true" />
  </button>
</LiquidGlass>

interactive adds a pointer animation to a div; it does not turn it into a button. Put a native button or link inside for keyboard access, activation and focus. The utility classes in these examples assume Tailwind; equivalent CSS works too.

Dark sheet / panel

<LiquidGlass radius={56} tint="dark" className="p-12">
  <p className="text-white text-4xl">It'll be fantastic weather…</p>
</LiquidGlass>

Glass on glass (e.g. a tab bar selection droplet). Render the inner glass as a sibling positioned over the outer one, not as a child (see Gotchas):

<div className="relative">
  <LiquidGlass radius={999} className="h-16">{tabs}</LiquidGlass>
  <div className="absolute inset-1 pointer-events-none">
    <LiquidGlass radius={999} blur={0} tint="rgba(255,255,255,.05)"
      style={{ width: "25%", height: "100%", transform: `translateX(${active * 100}%)` }} />
  </div>
</div>

A full working version, including the stretch while it slides, is in demo/src/Scenes.tsx.

Props

For most uses, set the size with CSS and optionally choose radius, tint and interactive. The optical controls below are optional tuning; leave bezel and thickness unset to derive them from the measured size.

PropDefaultDescription
radius32Corner radius in px. 999 for pills and circles.
bezelautoWidth of the curved, light-bending rim. Auto ≈ ¼ of the short side, capped by radius and 56.
thickness1.5 × bezelGlass height. Taller glass bends more.
ior1.5Index of refraction (water ≈ 1.33).
profile"squircle"Rim surface: "squircle", "circle" or "lip".
refraction1Multiplier on top of the physical bend.
dispersion0.06Colour separation. 0 disables it (single filter pass).
blur3Frost in px. 0 = perfectly clear glass.
saturation1.5Backdrop vibrancy.
tint"light""light", "dark" or any CSS colour.
specular1Edge highlight strength, 0-1.
lightAngle-135Light direction in degrees (-90 = top, -135 = top-left).
interactivefalsePress-to-grow and touch glow.

Every other div prop (className, style, onClick, role, …) is passed through.

Responsive layout and geometry

Width and height can use rem, %, vw, grid or flex layouts. The component measures the border box in CSS pixels and regenerates its maps when that box changes, including padding and borders. CSS pixels are the coordinate system of the generated filter, not physical device pixels.

<LiquidGlass radius={999} style={{ width: "100%", maxWidth: "40rem", height: "4rem" }}>
  <nav>…</nav>
</LiquidGlass>

The geometry props (radius, bezel, thickness, blur) take numbers in CSS pixels. Explicit values stay fixed when the root font size changes; they do not accept rem strings or CSS variables. A design system that needs those values to follow font-relative tokens must resolve the tokens to CSS pixels and update the props. The default bezel adapts within its documented limits; it is not proportional scaling of every optical parameter.

ior must be finite and greater than zero, and thickness must be finite and non-negative. Invalid optical inputs throw a RangeError. The map builders clamp the bezel to at least one CSS pixel and at most half the short side (with a one-pixel minimum); the low-level refractionProfile requires a finite positive bezel.

How it works

flowchart LR
  A[ResizeObserver<br/>element size] --> B[Snell's law over<br/>squircle bezel]
  B --> C[Displacement map<br/>R = x, G = y]
  A --> D[Specular rim map]
  A --> E[Tint mask]
  C --> F["SVG filter<br/>feImage → feDisplacementMap ×3"]
  F --> G["backdrop-filter:<br/>blur() url(#filter) saturate()"]
  D --> H[plus-lighter overlay]
  E --> I[masked tint layer]
  1. Optics. For each distance across the bezel, the surface slope of the squircle profile gives a normal. A straight-down view ray is refracted into the glass and followed to the content plane. The sideways offset is the displacement: 0 on the flat plateau, large near the edge.
  2. Map. That 1-D curve is swept around the rounded-rect outline along the inward normal and encoded into R/G, where 128 means no shift. feDisplacementMap then samples the backdrop from further inside the glass near the rim, which reads as magnification.
  3. Compositing. The filter is referenced from backdrop-filter on the component root. A masked tint, the specular map (mix-blend-mode: plus-lighter) and your content sit on top.

The deep dive is in skills/liquid-glass/references/theory.md.

Browser support

EngineResult
Blink: Chrome, Edge, Arc, Brave, OperaFull effect: refraction, dispersion, specular, frost
WebKit: Safari and every iOS browserFrosted fallback: blur, tint and specular rim, no refraction
Gecko: FirefoxSame frosted fallback

Only Blink renders SVG filters referenced from backdrop-filter. The other engines accept the syntax but draw nothing, so a CSS cascade fallback isn't reliable there. The component detects Blink and only adds url(#filter) there.

Gotchas

No refraction at all, the page just shows through the glass? You have a backdrop root in the way.

  • An ancestor with filter, opacity < 1, mask, clip-path, mix-blend-mode, backdrop-filter, or children that blend into it, cuts the backdrop off at that ancestor. The glass then refracts an empty image. That's why backdrop-filter sits on the component root, never on an inner layer. transform and overflow: hidden are fine.
  • Glass inside glass can't see the outer glass's refraction. Use siblings positioned on top (see Usage).
  • Give the glass something to bend. Over a flat colour, any glass looks like a tinted rectangle. Refraction shows over images, text and edges.

Static / zero-JS variant

For fixed-size elements, the same optics are available as a Python script that writes a PNG and prints the matching scale:

pip install -r scripts/requirements.txt
python3 scripts/generate-displacement-map.py --width 700 --height 64 --radius 32 \
  --output public/liquid-lens-map.png
# → Use it with: <feDisplacementMap scale="24.0" xChannelSelector="R" yChannelSelector="G" />

Generate the map at the element's exact CSS size; a stretched map puts the bend in the wrong place.

Demo

Open the live demo — no installation required.

Glass lab · Showcase · Classic demo

Chromium shows the full refraction effect; other browsers get the frosted fallback. The demo deploys to GitHub Pages after successful checks on main.

To run locally:

cd demo
npm install
npm run dev
URLScene
/Homepage with draggable glass and links to all demos
/?page=labSquircle, orb and pill lenses; draggable with mouse, touch or arrow keys; live backdrop, refraction and frost controls
/?page=showcaseInteractive artwork gallery, music interface and weather panel
/?page=classicThe original Music and Siri collection
/?scene=musicApple Music style tab bar with sliding droplet, mini player and search button over album art
/?scene=siriDark glass panel over a ribbon wallpaper
/?scene=playgroundDraggable lenses over text, stripes and a grid
/?scene=bannerThe header image of this README
/?scene=originalThe v1 technique, for comparison

Every prop can be tuned from the URL, for example /?scene=playground&thickness=80&dispersion=0.2&blur=0.

The demo imports @vepando/liquid-glass-react by name; Vite aliases that name to src/, so you get HMR on the library source without a build step.

Before and after

v1: one stretched static map, milky tintv2: physical, per-element, clear rim
Top: v1 original, bottom: v2 Mini player and tab bar close-up
Dark panel rim close-up

For AI coding agents

skills/liquid-glass/ is a self-contained skill (SKILL.md, assets and theory) that you can hand to Claude Code or any other coding agent to implement the effect end-to-end, including the troubleshooting table for the common failure modes.

Repository layout

src/                  the package: LiquidGlass.tsx · maps.ts · liquid-glass.css · index.ts
dist/                 build output (npm run build), published to npm
examples/             LiquidGlassPill.tsx
demo/                 Vite + React showcase
scripts/              generate-displacement-map.py (static variant)
skills/liquid-glass/  skill for AI coding agents
docs/                 images used in this README

Credits

The refraction model follows the approach described by kube.io in Liquid Glass in the browser: refraction with CSS and SVG. Liquid Glass is a design language by Apple; this project is not affiliated with Apple.

Development

npm install
npm run build      # tsup → dist/ (ESM, CJS, .d.ts, style.css)
npm run typecheck
npm test           # geometry regressions; Node 22.18+ or 24+
cd demo && npm install && npm run dev

Publishing: npm publish (runs typecheck and build first via prepublishOnly).

License

MIT

backdrop-filter
css
fedisplacementmap
frontend
glassmorphism
liquid-glass
nextjs
react
svg-filters
ui-design

LeonardSEO/liquid-glass-react

Real Apple-style "Liquid Glass" edge refraction for React/Next.js using a single SVG feDisplacementMap filter | no WebGL, no canvas rendering, ~5KB

TypeScript

7

10 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

I built a React liquid glass component that refracts the background at the edges. No WebGL (r/reactjs)

There are already plenty of liquid glass libraries. What I wanted was a clear centre with a curved rim that magnifies and stretches the content behind it. So I modelled the rim as a lens. The component uses Snell’s law to calculate refraction, generates an SVG displacement map for each element’s…

0

Oct 12, 2026

README

Liquid Glass for React: glass pills and orbs refracting a ribbon wallpaper

Liquid Glass for React

Apple's iOS 26 / macOS 26 Liquid Glass material for the web.
Physically based refraction, a specular rim and touch-reactive glass.
No WebGL, no canvas snapshots, no per-frame JavaScript.

npm bundle size MIT license React 18+ Next.js ready Zero dependencies Full effect in Chromium

Try the live demo — no installation needed
https://leonardseo.github.io/liquid-glass-react/


Most "liquid glass" CSS on the web is backdrop-filter: blur() in a rounded box. Real Liquid Glass bends light: the centre stays clear, while the curved rim magnifies and stretches whatever is behind it and catches a bright edge highlight.

This library models that rim as an actual lens. It traces light through it with Snell's law, writes the result into an SVG displacement map sized to each element, and lets the browser apply it in its normal backdrop-filter pass.

npm install @vepando/liquid-glass-react
import "@vepando/liquid-glass-react/style.css"
import { LiquidGlass } from "@vepando/liquid-glass-react"

<LiquidGlass radius={999} interactive style={{ height: 64 }}>
  <nav>…</nav>
</LiquidGlass>

Music app tab bar with sliding glass droplet and mini player; dark Siri-style glass panel

Contents

Features

  • Physically based refraction. The rim is a convex squircle bezel. Rays are refracted at n = 1.5 and traced down to the content beneath. The centre stays undistorted and the rim magnifies.
  • Pixel-exact maps per element. Each map is generated for the element's measured size and regenerated on resize, so the bend sits right on the curve whatever the shape.
  • Clear rim, tinted centre. The tint fades out across the bezel, so the refracted backdrop shows bright at the edge, as in Apple's glass.
  • Angle-dependent specular. A crisp edge line plus a soft inner glow that follows a configurable light direction.
  • Chromatic dispersion. R, G and B bend by slightly different amounts for a faint colour fringe on high-contrast edges.
  • Touch interaction. interactive adds a springy press-to-grow and a glow from the touch point.
  • Light and dark tints, or any CSS colour.
  • SSR safe. A frosted fallback renders on the server and upgrades on mount, without hydration mismatches.
  • Cached maps. Identical controls share maps. New sizes and optical settings generate maps synchronously; large panels and continuous resizing can be expensive. SVG backdrop rendering still costs work every frame, especially with dispersion. Many-element rendering has not been benchmarked across browsers and devices.
  • Zero dependencies. React 18+ is the only peer dependency. ESM + CJS + TypeScript types, about 5 KB gzipped.

Install

npm install @vepando/liquid-glass-react
# or: pnpm add @vepando/liquid-glass-react · yarn add @vepando/liquid-glass-react · bun add @vepando/liquid-glass-react

Import the stylesheet once, e.g. in your root layout or entry file:

import "@vepando/liquid-glass-react/style.css"

Then use the component anywhere:

import { LiquidGlass } from "@vepando/liquid-glass-react"

Next.js App Router: the bundle is already marked "use client", so you can render <LiquidGlass> straight from a server component. Put the CSS import in app/layout.tsx. Tested with next build and React 18/19 SSR.

Prefer to own the code? The source is three files in src/. The copy-paste version in skills/liquid-glass/assets/ works without the package.

Usage

Floating navbar

<LiquidGlass radius={999} className="h-16 w-full max-w-3xl">
  <nav className="h-full flex items-center justify-between px-6">…</nav>
</LiquidGlass>

Round icon button

<LiquidGlass radius={999} interactive className="h-16 w-16">
  <button type="button" aria-label="Search" onClick={openSearch}
    className="h-full w-full rounded-full border-0 bg-transparent cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2">
    <SearchIcon aria-hidden="true" />
  </button>
</LiquidGlass>

interactive adds a pointer animation to a div; it does not turn it into a button. Put a native button or link inside for keyboard access, activation and focus. The utility classes in these examples assume Tailwind; equivalent CSS works too.

Dark sheet / panel

<LiquidGlass radius={56} tint="dark" className="p-12">
  <p className="text-white text-4xl">It'll be fantastic weather…</p>
</LiquidGlass>

Glass on glass (e.g. a tab bar selection droplet). Render the inner glass as a sibling positioned over the outer one, not as a child (see Gotchas):

<div className="relative">
  <LiquidGlass radius={999} className="h-16">{tabs}</LiquidGlass>
  <div className="absolute inset-1 pointer-events-none">
    <LiquidGlass radius={999} blur={0} tint="rgba(255,255,255,.05)"
      style={{ width: "25%", height: "100%", transform: `translateX(${active * 100}%)` }} />
  </div>
</div>

A full working version, including the stretch while it slides, is in demo/src/Scenes.tsx.

Props

For most uses, set the size with CSS and optionally choose radius, tint and interactive. The optical controls below are optional tuning; leave bezel and thickness unset to derive them from the measured size.

PropDefaultDescription
radius32Corner radius in px. 999 for pills and circles.
bezelautoWidth of the curved, light-bending rim. Auto ≈ ¼ of the short side, capped by radius and 56.
thickness1.5 × bezelGlass height. Taller glass bends more.
ior1.5Index of refraction (water ≈ 1.33).
profile"squircle"Rim surface: "squircle", "circle" or "lip".
refraction1Multiplier on top of the physical bend.
dispersion0.06Colour separation. 0 disables it (single filter pass).
blur3Frost in px. 0 = perfectly clear glass.
saturation1.5Backdrop vibrancy.
tint"light""light", "dark" or any CSS colour.
specular1Edge highlight strength, 0-1.
lightAngle-135Light direction in degrees (-90 = top, -135 = top-left).
interactivefalsePress-to-grow and touch glow.

Every other div prop (className, style, onClick, role, …) is passed through.

Responsive layout and geometry

Width and height can use rem, %, vw, grid or flex layouts. The component measures the border box in CSS pixels and regenerates its maps when that box changes, including padding and borders. CSS pixels are the coordinate system of the generated filter, not physical device pixels.

<LiquidGlass radius={999} style={{ width: "100%", maxWidth: "40rem", height: "4rem" }}>
  <nav>…</nav>
</LiquidGlass>

The geometry props (radius, bezel, thickness, blur) take numbers in CSS pixels. Explicit values stay fixed when the root font size changes; they do not accept rem strings or CSS variables. A design system that needs those values to follow font-relative tokens must resolve the tokens to CSS pixels and update the props. The default bezel adapts within its documented limits; it is not proportional scaling of every optical parameter.

ior must be finite and greater than zero, and thickness must be finite and non-negative. Invalid optical inputs throw a RangeError. The map builders clamp the bezel to at least one CSS pixel and at most half the short side (with a one-pixel minimum); the low-level refractionProfile requires a finite positive bezel.

How it works

flowchart LR
  A[ResizeObserver<br/>element size] --> B[Snell's law over<br/>squircle bezel]
  B --> C[Displacement map<br/>R = x, G = y]
  A --> D[Specular rim map]
  A --> E[Tint mask]
  C --> F["SVG filter<br/>feImage → feDisplacementMap ×3"]
  F --> G["backdrop-filter:<br/>blur() url(#filter) saturate()"]
  D --> H[plus-lighter overlay]
  E --> I[masked tint layer]
  1. Optics. For each distance across the bezel, the surface slope of the squircle profile gives a normal. A straight-down view ray is refracted into the glass and followed to the content plane. The sideways offset is the displacement: 0 on the flat plateau, large near the edge.
  2. Map. That 1-D curve is swept around the rounded-rect outline along the inward normal and encoded into R/G, where 128 means no shift. feDisplacementMap then samples the backdrop from further inside the glass near the rim, which reads as magnification.
  3. Compositing. The filter is referenced from backdrop-filter on the component root. A masked tint, the specular map (mix-blend-mode: plus-lighter) and your content sit on top.

The deep dive is in skills/liquid-glass/references/theory.md.

Browser support

EngineResult
Blink: Chrome, Edge, Arc, Brave, OperaFull effect: refraction, dispersion, specular, frost
WebKit: Safari and every iOS browserFrosted fallback: blur, tint and specular rim, no refraction
Gecko: FirefoxSame frosted fallback

Only Blink renders SVG filters referenced from backdrop-filter. The other engines accept the syntax but draw nothing, so a CSS cascade fallback isn't reliable there. The component detects Blink and only adds url(#filter) there.

Gotchas

No refraction at all, the page just shows through the glass? You have a backdrop root in the way.

  • An ancestor with filter, opacity < 1, mask, clip-path, mix-blend-mode, backdrop-filter, or children that blend into it, cuts the backdrop off at that ancestor. The glass then refracts an empty image. That's why backdrop-filter sits on the component root, never on an inner layer. transform and overflow: hidden are fine.
  • Glass inside glass can't see the outer glass's refraction. Use siblings positioned on top (see Usage).
  • Give the glass something to bend. Over a flat colour, any glass looks like a tinted rectangle. Refraction shows over images, text and edges.

Static / zero-JS variant

For fixed-size elements, the same optics are available as a Python script that writes a PNG and prints the matching scale:

pip install -r scripts/requirements.txt
python3 scripts/generate-displacement-map.py --width 700 --height 64 --radius 32 \
  --output public/liquid-lens-map.png
# → Use it with: <feDisplacementMap scale="24.0" xChannelSelector="R" yChannelSelector="G" />

Generate the map at the element's exact CSS size; a stretched map puts the bend in the wrong place.

Demo

Open the live demo — no installation required.

Glass lab · Showcase · Classic demo

Chromium shows the full refraction effect; other browsers get the frosted fallback. The demo deploys to GitHub Pages after successful checks on main.

To run locally:

cd demo
npm install
npm run dev
URLScene
/Homepage with draggable glass and links to all demos
/?page=labSquircle, orb and pill lenses; draggable with mouse, touch or arrow keys; live backdrop, refraction and frost controls
/?page=showcaseInteractive artwork gallery, music interface and weather panel
/?page=classicThe original Music and Siri collection
/?scene=musicApple Music style tab bar with sliding droplet, mini player and search button over album art
/?scene=siriDark glass panel over a ribbon wallpaper
/?scene=playgroundDraggable lenses over text, stripes and a grid
/?scene=bannerThe header image of this README
/?scene=originalThe v1 technique, for comparison

Every prop can be tuned from the URL, for example /?scene=playground&thickness=80&dispersion=0.2&blur=0.

The demo imports @vepando/liquid-glass-react by name; Vite aliases that name to src/, so you get HMR on the library source without a build step.

Before and after

v1: one stretched static map, milky tintv2: physical, per-element, clear rim
Top: v1 original, bottom: v2 Mini player and tab bar close-up
Dark panel rim close-up

For AI coding agents

skills/liquid-glass/ is a self-contained skill (SKILL.md, assets and theory) that you can hand to Claude Code or any other coding agent to implement the effect end-to-end, including the troubleshooting table for the common failure modes.

Repository layout

src/                  the package: LiquidGlass.tsx · maps.ts · liquid-glass.css · index.ts
dist/                 build output (npm run build), published to npm
examples/             LiquidGlassPill.tsx
demo/                 Vite + React showcase
scripts/              generate-displacement-map.py (static variant)
skills/liquid-glass/  skill for AI coding agents
docs/                 images used in this README

Credits

The refraction model follows the approach described by kube.io in Liquid Glass in the browser: refraction with CSS and SVG. Liquid Glass is a design language by Apple; this project is not affiliated with Apple.

Development

npm install
npm run build      # tsup → dist/ (ESM, CJS, .d.ts, style.css)
npm run typecheck
npm test           # geometry regressions; Node 22.18+ or 24+
cd demo && npm install && npm run dev

Publishing: npm publish (runs typecheck and build first via prepublishOnly).

License

MIT

backdrop-filter
css
fedisplacementmap
frontend
glassmorphism
liquid-glass
nextjs
react
svg-filters
ui-design