# Metal FX

By **jakubantalik** · Software & Tools

Animated WebGL liquid-metal shader for React buttons and chips, one component, three presets, zero layout shifts.

- Source: https://metal.jakubantalik.com
- Repository: https://github.com/Jakubantalik/metal-fx
- Install: `npm i metal-fx`
- Tags: react, webgl, animation, ui-component, open-source, shader, dark-mode, npm
- Pricing: free
- Upvotes: 0

## Features

- Real-time animated liquid-metal ring rendered in WebGL
- Button (pill) and circle variants with tuned ring widths
- Three color presets: chromatic, silver, gold
- Auto, dark, and light theme modes with live OS-theme subscription
- Strength prop (0-1) to scale effect intensity
- Proximity reflection for neighbouring elements (dark mode only)
- IntersectionObserver pauses off-screen instances to save GPU
- Pause prop to freeze shader on current frame

---

## Why it matters

Metal FX gives React UIs the kind of polished, animated metal ring effect that typically requires a custom WebGL setup from scratch. It ships as a single wrapper component, `npm install metal-fx`, so a call-to-action button can go from flat to iridescent in minutes, not days.

## The big picture

Pure CSS cannot replicate a real-time shader. Three.js or raw WebGL can, but both demand significant setup. Per the README, Metal FX compiles the shader once and reuses one shared WebGL context across every mounted instance on the page. A single `requestAnimationFrame` loop drives all of them, so adding a second Metal FX button costs almost nothing beyond one extra `drawImage` copy per frame.

## How it works

Wrap a child element with `<MetalFx variant="button">` or `<MetalFx variant="circle">`. The component measures the child, paints an animated ring on top with `pointer-events: none`, and leaves the child fully interactive. It does not force dimensions: size the child as usual and the wrapper matches it.

## Zoom in

**Presets and theming.** Three bundled palettes cover most use cases: `chromatic` (iridescent rainbow, default), `silver` (cool steel), and `gold` (warm gold). The `theme` prop accepts `auto`, `dark`, or `light`. `auto` subscribes to `matchMedia('(prefers-color-scheme: dark)')` and switches the frame instantly when the user toggles their system theme.

**Effect controls.** The `strength` prop runs from `0` (invisible) to `1` (full, the default) and scales canvas and glow opacity without touching the shader animation. The `paused` prop freezes the shader on its current frame while keeping the metal silhouette visible.

**Proximity reflection.** Pass a `reflectionTargets` array of refs and neighbouring elements receive a soft mirrored reflection of the ring. The README notes this feature is dark-mode only: reflections are skipped in light mode automatically, so there is no DOM scanning or per-frame cost on light backgrounds.

## Yes, but

Metal FX is best on a handful of focal UI elements, not scattered across every interactive surface. Skip it for tables, data-dense dashboards, navigation menus, or any surface where animation competes with reading. The effect is deliberately high-contrast; overuse flattens its impact and adds unnecessary GPU work. If your project already uses CSS `@property` animations for a subtle glow, Metal FX is the step up to a physically plausible shader ring, not a drop-in replacement for simpler transitions.

## The bottom line

Metal FX is a focused, MIT-licensed tool for React developers who want a real WebGL metal shader on CTA buttons without building one. The shared-context architecture keeps the performance cost low, the preset system covers the common palette needs, and SSR safety means it fits Next.js projects out of the box. Find it at [github.com/Jakubantalik/metal-fx](https://github.com/Jakubantalik/metal-fx) and install with `npm install metal-fx`.

## FAQ

### What is Metal FX?

Metal FX (`metal-fx` on npm) is a React component that wraps any button, chip, or icon element with a real-time animated liquid-metal ring rendered in WebGL. It ships with three color presets (chromatic, silver, gold), automatic dark/light theming, a proximity reflection feature for neighbouring elements, and full SSR safety for frameworks like Next.js. The effect sits above the wrapped child with `pointer-events: none`, so the underlying element remains fully interactive.

### How do I install and use Metal FX?

Install via npm with `npm install metal-fx`, then import the `MetalFx` component and wrap your target element: `<MetalFx variant="button"><button>Upgrade to Pro</button></MetalFx>`. The `variant` prop accepts `button` (pill silhouette, 1 px ring) or `circle` (compact, 2 px ring). Size your child element as normal, the wrapper is `display: inline-flex` and matches the child's dimensions automatically. No WebGL setup or shader code is required.

### Is Metal FX free and open source?

Yes. Metal FX is released under the MIT license by Jakub Antalik and published publicly on GitHub at github.com/Jakubantalik/metal-fx. The MIT license allows free use in commercial and personal projects. There is no paid tier, API key, or usage restriction described in the README.

### What is Metal FX best for?

Metal FX is best suited for high-attention UI elements: primary call-to-action buttons, send buttons, icon chips, or upgrade prompts where a premium tactile visual adds meaning. The README's examples use it for 'Upgrade to Pro' pills and circular send icons. The effect is intentionally high-contrast and animated, so it works best on a small number of focal elements rather than across every interactive surface.

### How does Metal FX handle performance with multiple instances?

A single shared WebGL context is reused across every mounted `<MetalFx>` on the page and the shader is compiled only once, per the README. One `requestAnimationFrame` loop drives all instances; per-frame work for each visible mount is one `gl.drawArrays` call plus one `drawImage` copy. `IntersectionObserver` automatically pauses per-instance copies when the element scrolls off-screen, and when every instance is off-screen the GL render is skipped entirely. This architecture keeps the GPU cost low even when several instances are mounted simultaneously.

### What are the key limitations of Metal FX?

Metal FX is a React-only library, no Vue, Svelte, or vanilla JS adapters are mentioned in the README. Proximity reflection only activates in dark mode; it is automatically skipped in light mode with no per-frame cost. Preset customisation is limited to three built-in palettes (chromatic, silver, gold) and the `strength` (0-1) prop; deep shader modification is not documented. The effect is also better avoided on content-dense surfaces like tables or dashboards, where animation competes with reading rather than reinforcing a focal action.

---
[View on Analog](https://analoghq.ai/jakubantalik/software-tools/metal-fx)