Waveform

Displays supplied audio amplitudes with optional seeking and editable selection bounds.

Find the passage

Select a region or move the playhead.

Use it for

  • A supplied waveform for an audio recording.
  • Seeking or selecting an interval in normalised zero-to-one coordinates.

Not for

  • Generating or decoding audio data; provide amplitude samples.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { Waveform } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/waveform.

2. Vendor the source

npx @noorddev/vlak-cli add waveform

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/waveform.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { Waveform } from "@noorddev/vlak-react";

<Waveform samples={[0.2, 0.5, 0.8, 0.3, 0.7, 0.4]} label="Interview waveform" value={position} onValueChange={setPosition} region={region} onRegionChange={setRegion} />

Waveform

A waveform from supplied amplitude data, optionally scrubbed through a native range.

PropTypeDefaultDescription
samplesrequiredreadonly number[]Amplitudes from zero to one; values are clamped.
labelrequiredstring
valuenumber
defaultValuenumber0
onValueChange(position: number) => void
disabledbooleanfalse
regionWaveformRegion
defaultRegionWaveformRegion{ start: 0, end: 1 }
onRegionChange(region: WaveformRegion) => void

Also accepts Omit<HTMLAttributes<HTMLDivElement>, "defaultValue">.

KeysDoes
Tab, Arrow keys, Home, EndOperates the native seek range and optional selection start and end ranges.
<div class="rs-waveform"><svg class="rs-waveform-plot" viewBox="0 0 80 48" role="img" aria-label="Audio waveform"><path d="M0 24 H10 V10 H12 V38 H14 V24 H30 V4 H32 V44 H34 V24 H80" fill="none" stroke="currentColor" /></svg></div>
.rs-waveform.rs-waveform-stage.rs-waveform-plot.rs-waveform-input.rs-waveform-region.rs-waveform-region-controls.rs-waveform-label.rs-waveform-bar.rs-waveform-played