← All components
Motion / effect
Voice Glow
Light, dots and wireframe landscapes give sound a physical presence. Four complete contexts, one full voice engine.
Take it with you.
SOURCE ACCESS
Preview freely. Unlock the files.
Enter the shared password to copy the complete source, download every file, and install components in your app.
Access lasts 24 hours. Your preview settings stay with you.
Component notes
- Three complete looks retain the full engine: Glow uses eight palettes and typed custom lobe/band colors; Dots and Lines share the perspective, gravity and surface model. The palette control applies only to Glow.
- Composer, Recording pill, Phone and Processing are original portable contexts. Primitive usage includes a sized host. For your own content, import VoiceBeam and supply a child; type selects tuned defaults, and explicit geometry props override those defaults.
- Simulation and manual input require no permission. Use microphone is an explicit local action in the Complete audio contexts; capture is neither recorded, uploaded nor persisted. Processing never requests devices. Stop, signal-mode/scene change and unmount dispose owned tracks, including late grants.
- Controlled source accepts caller-owned streams, number or getter level, and callbacks. Borrowed tracks are never stopped. Advanced source demonstrates a getter, custom colors, band colors and typed geometry; its custom palette is authored separately from the scalar palette control.
- The full typed API below covers every public option: geometry, envelope, processing, styling and callbacks. Additional per-layer/band/core/hue tuning, colors, bandColors, style, css, streams and callbacks are supplied in React code through VoiceBeamProps, never scalar metadata. Examples.tsx, ControlledExample.tsx, AdvancedExample.tsx and types.ts are included in every distribution.
- Appearance and Pause preserve drafts and the signal clock; Replay restarts decoration without remounting local work. Reduced motion, hidden and offscreen instances stop continuous frames. Per-instance surface work is bounded; physical FPS and cross-browser certification are not claimed.
- Legacy Demo.tsx retains its existing mode, level, colorVariant, reach and glowSize interface. Full MIT notices and portable shared lifecycle helpers are required. No paid recipes or reference artwork are included.
React 19.2Modern browsers
Libraries.dev — Jakub Antalik · MIT. See bundled notice.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
children (required) | ReactNode | undefined | Content to wrap with the voice beam effect |
type | VoiceBeamType | 'default' | Host preset: 'default' (chat input), 'pill' (recording pill) or 'mobile' (bottom of a phone screen). Sets the defaults of the geometry props below for that host; any prop you pass still wins. |
look | VoiceBeamLook | 'glow' | How the voice is drawn: coloured light, or a surface of dots or lines that the voice raises and gravity brings down. |
dotSize | number | 1 | Dot radius, as a multiplier on the tuned size. `look="dots"` only. |
dotGap | number | 1 | Spacing between dots, as a multiplier — below 1 is a denser, finer surface, above 1 a sparser, coarser one. `look="dots"` only. |
dotShape | VoiceBeamDotShape | 'round' | The dots' shape: round, or square for a pixel grid. `look="dots"` only. |
lineWidth | number | 1 | Line width, as a multiplier on the tuned width (lines thin out into the distance). `look="lines"` only. |
lineGap | number | 1 | Spacing between lines, as a multiplier — the rows and the columns alike. `look="lines"` only. |
linePattern | VoiceBeamLinePattern | 'rows' | Which way the lines run: across the surface, into the depth, or both. `look="lines"` only. |
seeThrough | boolean | false | Draw the lines as a wireframe: those behind a raised ridge show through it instead of being hidden by it. `look="lines"` only. |
texture | number | 0.6 | Organic texture, 0–1: a slow ripple the flow carries across the surface. 0 is a still sheet that only the voice moves. Dots and lines. |
gravity | number | 1 | How hard the surface falls when the voice drops, as a multiplier on its gravity. Lower floats down, higher drops like sand. Dots and lines. |
surfaceHeight | number | 1 | How tall the surface stands along the bottom, as a multiplier — how far back the sheet runs, and so how much of the host it covers. Dots and lines. |
surfaceCurve | number | 1 | How far the surface arcs, as a multiplier: its sides and far edge fall away like a horizon. 0 is a flat sheet; below 0 it cups upward instead. Dots and lines. |
surfaceTail | number | 0 | The surface's tails: how far its ends rise toward the corners, as a share of the sheet's height — the ends curl up into the host's corners instead of running flat into its sides. Below 0 they drop away instead. Dots and lines. |
surfaceTailPosition | number | 0.6 | Where the tails start, as a share of the distance from the centre to the side (0.8 = only the last 20%); they reach their full lift at the edge. |
surfaceTailCurve | number | 2.4 | Exponent of the tails' rise: 1 a straight ramp, 2 a parabola, higher a hook that stays low and whips up at the edge. |
surfaceFade | number | 0.2 | How far in from the sides the surface dissolves, as a share of its half-width, 0–1. 0 runs it hard into the edges; 1 fades it from the centre out. Dots and lines. |
scale | number | 1 (0.45 for `type="pill"`) | Size of the whole effect. Multiplies every pixel dimension at once — lobes, their spacing, the visible range, the bend, the band, the core, the bloom blur, the flow speed — so the glow grows or shrinks as one thing, on top of the type preset and the individual geometry props. |
stream | MediaStream | null | undefined | Audio to react to. When set, the beam analyses this stream (level plus low / mid / high bands) and ignores `level`. Get one from the application’s `getUserMedia` / WebRTC capture flow or `useVoiceCapture`. |
level | VoiceBeamLevel | 0 | Manual drive, 0–1, used when no `stream` is given. A number re-renders on change; a getter is sampled once per frame without re-rendering. |
sensitivity | number | 3.1 | Input gain on the analysed audio. The default suits a laptop microphone at conversational distance; raise it for quiet sources, lower it for a close or hot one. |
threshold | number | 0.015 | Noise gate, 0–1. Levels below it read as silence, so room hum and fan noise do not keep the beam twitching. |
attack | number | 0.325 | Seconds the glow takes to rise toward a louder level. |
release | number | 0.86 | Seconds the glow takes to settle after the sound drops. |
idle | number | 0.23 | Resting presence, 0–1 — how much the beam breathes while silent so it never looks dead. 0 hides it completely between sounds. |
breatheDuration | number | 5.2 | Period of the idle breathing in seconds. |
reach | number | 1.2 (1.8 on the light theme; 1.35 for `pill`, 3 for `mobile`) | How tall the glow grows at full level, as a multiple of its resting height. The rise is centered on the bottom edge. |
spread | number | 1.05 (0.8 on the light theme; 1.1 for `pill`, 0.45 for `mobile`) | How far the glow widens at full level, as a fraction of its resting width. Side lobes drift outward as well, so a loud sound spreads. |
bands | boolean | true | Let the low / mid / high bands move the colored lobes independently (center follows the lows, the sides the mids and highs). With a manual `level` the bands are synthesised from the level, so the lobes still dance. Off, every lobe follows the one level. |
flow | number | 48 | How fast the spectrum travels sideways, in px per second at full level — the lobes slide left to right while a voice is heard and rest when it stops, so every colour takes a turn at the centre. Negative flows right to left; 0 holds the lobes in place. |
processing | boolean | false | Processing state — turn it on once the voice has been captured and something is working on it. The lobes gather into one compact beam that travels the glow's range left to right and back, eased at each end and looped — border-beam's `line` type, confined to the voice glow — and the glow is held lit at `processingLevel` so the beam has colour. Both blend in and out smoothly. The distortion settles out in about a quarter second and stays off while processing. |
processingDuration | number | 1.1 (1.05 for `type="mobile"`) | Seconds for one pass of the processing beam (left to right, or back again). |
processingLevel | number | 0.55 (0.35 for `type="mobile"`) | How lit the glow is held while processing, 0–1, as if a voice were speaking at that level. |
processingEase | number | 0.6 | Seconds the morph between the voice glow and the travelling beam takes, in either direction — the gather, the narrowing and the travel ease in and out over it. |
processingTravel | number | 1.55 (2 for `pill`, 1 for `mobile`) | How far the processing beam travels to each side, as a multiple of half the lobe ring: 1 sweeps the glow's resting spread, lower keeps it near the centre, higher runs it out to the corners. |
processingCurve | number | 2.1 | How the processing beam eases into each turn of its sweep: 1 runs at a constant speed and turns sharply, 2 slows smoothly into the ends, higher dwells there longer before heading back. |
cornerFollow | number | 0.45 (0 for `type="pill"`, 0.4 for `type="mobile"`) | How much the coloured glow rides the element's corner arcs while processing, 0–1: 0 keeps it flat along the bottom edge, 1 lifts it along the rounded corner as it passes through. The band line follows the corner either way. |
colorVariant | VoiceBeamColorVariant | 'colorful' | Color variant for the beam |
colors | string[] | undefined | Your own lobe colours, centre first then the pairs outward — up to seven, any CSS hex or rgb. Slots you leave out (or that fail to parse) keep the variant's colour for the theme. |
bandColors | { core?: string; above?: string; mid?: string; below?: string } | undefined | The band's colours: the core ridge and its chromatic fringes above, between and below. Any CSS hex or rgb; unset ones keep the theme's defaults (white core with red / green / blue fringes on dark, a pink core with rose / lavender / sky on light). |
theme | VoiceBeamTheme | 'dark' | Theme mode — adapts beam colors for dark or light backgrounds; 'auto' follows prefers-color-scheme |
staticColors | boolean | false | Disable the slow hue drift for static colors |
hueRange | number | 24 (dark) / 40 (light) | Hue drift range in degrees (the palette wanders ± this far) |
hueDuration | number | 12 (dark) / 8.5 (light) | Period of the hue drift in seconds |
active | boolean | true | Whether the effect is on. Off fades the beam out and stops the audio analysis. |
paused | boolean | false | Freezes the effect where it is — the glow, the band and the audio analysis all hold their last frame — without fading it out. Other props still shape the held frame, and the clocks resume where they stopped. |
replayToken | number | undefined | Change to reset the effect without remounting wrapped content. |
borderRadius | number | undefined | Custom border radius in pixels. When omitted, the component auto-detects the border-radius of the first child element. |
brightness | number | 1.15 (dark chat input) / 0.95 (light); the dark theme itself is 1.1, `pill` runs 1.35, `mobile` 1.2 on dark | Brightness multiplier for the glow |
saturation | number | 1.2 (dark) / 1.6 (light); `pill` and `mobile` run 1.5 on dark | Saturation multiplier for the glow |
glowSize | number | 1 | Multiplies the bloom blur radius, so the halo reads tighter (< 1) or wider and softer (> 1). |
strokeOpacity | number | 1 | Per-layer opacity multipliers on the theme's own: the crisp edge stroke, the soft inner light and the blurred bloom. The same knobs as the `--voice-stroke-opacity` / `--voice-inner-opacity` / `--voice-bloom-opacity` CSS hooks. |
innerOpacity | number | undefined | Typed primitive option. See the included canonical types and Advanced example for composition. |
bloomOpacity | number | undefined | Typed primitive option. See the included canonical types and Advanced example for composition. |
bend | number | 60 | Bend — how much, in px, the glow's top contour humps up at the centre at full level. The ceiling the glow is masked to gains that height in the middle and none at the ends, and a faint rim traces the curve, so the glow's outline bows upward with the voice like space bending around it. 0 keeps the contour at its plain ellipse. |
bandStrength | number | 1.55 (1.8 for `mobile`; on light 1.7, or 2 for `pill`) | Opacity of the band, 0 hides it. |
bandWidth | number | 2.15 | Thickness of the band. |
bandPosition | number | 0.35 | Height of the band's peak as a fraction of the glow's ceiling, 0.1–1.3. |
bandCurve | number | 1.75 | Bell exponent: below 2 an exponential, cusp-like rise; 2 a gaussian; above, a flatter top. |
bandSpread | number | 0.87 | Bell width as a fraction of the glow's half-range: small is a narrow spike with long tails, large a broad dome. |
bandSkew | number | 0.12 | Asymmetry, −0.6–0.6: positive widens the right side and steepens the left. |
bandOffset | number | -27 | Vertical shift of the whole band line in px; negative sinks it toward the edge. |
bandTail | number | 0.59 (0 for `pill`) | How far the band's ends rise again toward the corners, as a fraction of its peak, 0–1 — the line opens upward at the edges instead of dying flat. |
bandTailPosition | number | 0.67 | Where the tail's rise starts, as a share of the distance from the beam's centre to the element's edge (0.85 = only the last 15%); it always reaches the full lift exactly at the corner. |
bandTailCurve | number | 2.4 | Exponent of the rise: 1 a straight ramp, 2 a parabola, higher a hook that stays low and whips up at the corner. |
bandTailOverflow | number | 15 | Px the band runs past each side of the element, so the hook peaks outside and is cropped by the component's edge. Scales with `scale`. |
bandAberration | number | 0.89 | Chromatic aberration — how far the red and blue fringes split from the core, 0–1. |
distortion | number | 0.62 | Distortion — how much the glow under the band warps sideways, 0–1. A slowly drifting noise field displaces the inner light and the bloom horizontally, stronger as the voice rises, so the colours shimmer and stretch like light through bent space. Only the glow UNDER the band line warps — the layers are split at the line — and it is independent of `bandStrength`, so the line can be invisible and the warp strong. The edge stroke stays crisp. 0 turns the filter off entirely. |
distortionDetail | number | 2.3 | Grain of the distortion's noise: below 1 broad slow waves, above 1 finer ripples. |
glowWidth | number | 0.65 | Width of every colour lobe, all layers — on the dots and lines, the width of each hill. |
glowHeight | number | 1.25 | Height of every colour lobe, all layers. |
lobeSpacing | number | 0.85 | Distance between the lobes (and the ring the flow travels) — on the dots and lines, between the hills. |
rangeWidth | number | 0.75 | Width of the visible ellipse the glow is masked to. |
rangeHeight | number | 1 | Height of the visible ellipse the glow is masked to. |
softness | number | 1.07 | Where each lobe fades out — below 1 crisper, above 1 softer. |
coreSize | number | 1 | The white hot spot at the centre of the edge. |
coreLight | number | 0 (1.8 on the light theme) | The epicentre: a soft white wash under the band line at the centre of the edge, so the source reads lighter than the band. 0–3: up to 1 the wash's opacity, past 1 its solid white core widens and the whole wash grows, washing out more of the colour beneath. |
coreLightWidth | number | 1 | Width of the epicentre wash. |
coreLightHeight | number | 1 | Height of the epicentre wash. |
strokeScale | number | 1 | Size of the colours painted into the 1px edge stroke. |
innerScale | number | 1 | Size of the soft light inside the element. |
innerHeight | number | 1 | Extra height of the inner light — how far it reaches into the element. |
bloomScale | number | 1 | Size of the blurred halo. |
bloomHeight | number | 1 | Extra height of the halo — how far the soft light climbs. |
strength | number | 1 (dark) / 0.8 (light); 1 on both for `type="mobile"` | Overall strength/opacity of the effect (0–1). Only affects the beam layers — not the children. |
className | string | undefined | Additional class name for the container |
style | CSSProperties | undefined | Additional inline styles for the container |
css | string | undefined | Extra CSS appended after the beam's own generated stylesheet. Write `{id}` wherever the instance id belongs — the root is `[data-voice-beam="{id}"]`, its layers the `::before` / `::after` pseudo-elements and `[data-voice-beam-bloom]`, and keyframes are named `*-{id}` — and it is substituted per instance. |
onLevel | (level: number) => void | undefined | Called every frame with the smoothed level (0–1) the beam is showing. Handy for a meter or a "listening" label; avoid setting React state from it on every call. |
onActivate | () => void | undefined | Callback when the fade-in completes |
onDeactivate | () => void | undefined | Callback when the fade-out completes |