fluidity-js — Upgrade your UX
Demo & Examples →
bun add @jayf0x/fluidity-js
# npm / pnpm / aube
import { FluidImage , FluidText } from '@jayf0x/fluidity-js' ;
// Fluid text — reacts to cursor movement
export const Hero = ( ) => {
return (
< div style = { { width : '100%' , height : 400 } } >
< FluidText text = "Hello World" fontSize = { 140 } color = "#ffffff" />
</ div >
) ;
} ;
// Full-bleed fluid image
export const Cover = ( ) => {
return (
< div style = { { width : '100%' , height : '100vh' } } >
< FluidImage src = "/hero.jpg" algorithm = "aurora" />
</ div >
) ;
} ;
Use ref to trigger effects from code — scroll-driven splats, click bursts, attract particles:
import { useRef } from 'react' ;
import { FluidText } from '@jayf0x/fluidity-js' ;
export const Interactive = ( ) => {
const fluid = useRef < FluidHandle > ( null ) ;
return (
< >
< div style = { { width : '100%' , height : 400 } } >
< FluidText ref = { fluid } text = "Splash!" fontSize = { 120 } color = "#fff" />
</ div >
< button onClick = { ( ) => fluid . current ?. splat ( 200 , 200 , 8 , - 4 ) } > Splat</ button >
< button onClick = { ( ) => fluid . current ?. updateConfig ( { curl : 0.5 } ) } > Swirl</ button >
< button onClick = { ( ) => fluid . current ?. reset ( ) } > Reset</ button >
</ >
) ;
} ;
Method
What it does
reset()
Restart the simulation
updateConfig(patch)
Change any config value live
move({ x, y, strength? })
Simulate a pointer move
splat(x, y, vx, vy, strength?)
Inject fluid directly — safe to call many times per frame
Prop
Type
Default
text
string
—
fontSize
number
100
color
string
'#ffffff'
fontFamily
string
'sans-serif'
fontWeight
string | number
900
Prop
Type
Default
src
string
—
imageSize
string | number
'cover'
effect
number
0
Prop
Type
Default
config
Partial<FluidConfig>
—
preset
PresetKey
—
algorithm
FluidAlgorithm
'standard'
quality
FluidQuality
{ dpr: 1, sim: 0.5 }
backgroundColor
string
'#0a0a0a'
backgroundSrc
string
—
backgroundSize
string | number
'cover'
isMouseEnabled
boolean
true
isWorkerEnabled
boolean
true
useWebGPU
boolean
true
className
string
—
style
CSSProperties
—
Value
Vibe
'standard'
Colour overlay + gentle refraction (default)
'glass'
Bent-glass distortion, no colour
'ink'
Dense opaque pigment that accumulates and stains
'aurora'
Liquid metal / lava-lamp
'ripple'
Still water surface with Fresnel rim
< FluidImage src = "/photo.jpg" algorithm = "aurora" />
< FluidText text = "fluid" algorithm = "ripple" config = { { warpStrength : 0.03 } } / >
Control rendering resolution on two independent axes — both reactive at runtime.
Field
Range
Default
What it does
dpr
0.1–1
1
Canvas resolution as fraction of screen pixel ratio. 0.5 on Retina saves ~75% GPU fill.
sim
0.1–1
0.5
Simulation resolution. Lower = cheaper, less detail.
// Sharp canvas, cheap simulation
< FluidImage src = "/hero.jpg" quality = { { dpr : 1 , sim : 0.2 } } />
// Lower canvas res, full simulation quality
< FluidImage src = "/hero.jpg" quality = { { dpr : 0.5 , sim : 1 } } / >
Key
Default
Description
densityDissipation
0.992
How long ink lingers (0–1)
velocityDissipation
0.93
How fast fluid slows down (0–1)
pressureIterations
1
Quality vs. cost trade-off
curl
0.0001
Swirl intensity. 0.2–0.5 for visible eddies
splatRadius
0.004
Brush radius
splatForce
0.91
Force applied by brush
refraction
0.25
Background warp strength
specularExp
1.01
Specular highlight sharpness
shine
0.01
Highlight intensity
waterColor
[0, 0, 0]
Base fluid colour [R, G, B] (0–1)
glowColor
[0.7, 0.85, 1.0]
Glow / specular colour [R, G, B] (0–1)
warpStrength
0.015
UV warp intensity (aurora algorithm)
Works in all modern browsers. Automatically picks the best renderer available — no configuration needed.
Browser
Support
Chrome 113+
✅
Edge 113+
✅
Firefox
✅
Safari 17+
✅
Safari < 17
✅
Mobile Chrome
✅
Issues and PRs welcome. See CONTRIBUTING.md for setup and AGENTS.md for code conventions.
MIT © jayf0x