Plugins

What plugins are

Plugins are optional modules that add features on top of the core wavesurfer.js waveform player. Each plugin is a separate file you import only when you need it, so your bundle stays small if you use just a subset.

The eight official plugins are:

  • Regions — highlight and loop segments of audio
  • Timeline — a time ruler above or below the waveform
  • Spectrogram — a frequency-over-time visualization
  • Minimap — a small overview waveform for navigation
  • Hover — show a vertical line and timestamp under the cursor
  • Zoom — scroll-wheel / pinch zoom
  • Record — record audio from the microphone
  • Envelope — draw a volume / fade curve over the waveform

Importing

ESM (bundler or <script type="module">)

Each plugin ships as an ES module at dist/plugins/<name>.esm.js:

import WaveSurfer from 'wavesurfer.js'
import RegionsPlugin from 'wavesurfer.js/dist/plugins/regions.esm.js'
import TimelinePlugin from 'wavesurfer.js/dist/plugins/timeline.esm.js'

The same paths work with a CDN that serves npm packages:

import RegionsPlugin from 'https://unpkg.com/wavesurfer.js@7/dist/plugins/regions.esm.js'

UMD (plain <script> tag)

Load the core library first, then each plugin’s .min.js file. Every plugin attaches itself to the WaveSurfer global under a capitalised key:

<script src="https://unpkg.com/wavesurfer.js@7/dist/wavesurfer.min.js"></script>
<script src="https://unpkg.com/wavesurfer.js@7/dist/plugins/regions.min.js"></script>
<script src="https://unpkg.com/wavesurfer.js@7/dist/plugins/timeline.min.js"></script>
<script>
  // Globals: WaveSurfer.Regions, WaveSurfer.Timeline, WaveSurfer.Spectrogram,
  //          WaveSurfer.Minimap, WaveSurfer.Hover, WaveSurfer.Zoom,
  //          WaveSurfer.Record, WaveSurfer.Envelope
  const regions = WaveSurfer.Regions.create()
  const timeline = WaveSurfer.Timeline.create()
</script>

Registering

At construction time — the plugins option

Pass an array of plugin instances to WaveSurfer.create():

const regions = RegionsPlugin.create()
const timeline = TimelinePlugin.create()

const ws = WaveSurfer.create({
  container: '#waveform',
  url: '/audio.mp3',
  plugins: [regions, timeline],
})

All plugins in the array are initialised immediately when the WaveSurfer instance is created.

After construction — ws.registerPlugin()

Call registerPlugin at any point after create(). It initialises the plugin right away and returns the plugin instance:

const ws = WaveSurfer.create({ container: '#waveform', url: '/audio.mp3' })

// Register later — perhaps in response to a user action
const regions = ws.registerPlugin(RegionsPlugin.create())

Both approaches produce an identical result; the plugins option is just a convenience that calls registerPlugin for each entry internally.


Getting an instance back

Keep the reference

The simplest approach is to hold on to the reference returned by RegionsPlugin.create() or ws.registerPlugin():

// Option A: created with the plugins option
const regions = RegionsPlugin.create()
const ws = WaveSurfer.create({ container: '#waveform', plugins: [regions] })
regions.addRegion({ start: 1, end: 3 })

// Option B: registered after creation
const regions = ws.registerPlugin(RegionsPlugin.create())
regions.addRegion({ start: 1, end: 3 })

ws.getActivePlugins()

If you no longer have the original reference, you can retrieve all currently registered plugins:

const allPlugins = ws.getActivePlugins()
// Returns an array of GenericPlugin instances in registration order

Pitfalls

Register each plugin instance only once. Calling ws.registerPlugin() with the same instance twice is safe — wavesurfer.js silently skips the duplicate — but creating a new RegionsPlugin.create() and registering it again while the old one is still active will attach a second set of event listeners and DOM elements, leaking memory. Always call plugin.destroy() before replacing a plugin. See Performance for more on memory management.

React StrictMode mounts components twice in development, which causes WaveSurfer.create() — and therefore all plugins — to initialise twice. The second initialisation runs before the first one is cleaned up, so you can end up with duplicate plugin instances. Always return a cleanup function from useEffect that calls ws.destroy(), and guard the effect with a ref so creation only happens once. See Frameworks for a complete React example.


The plugins

Plugin Description
Regions Add coloured, draggable, and resizable regions to mark segments of audio
Timeline Render a time ruler with tick marks above or below the waveform
Spectrogram Visualise audio frequency content as a colour-mapped spectrogram
Minimap Display a small thumbnail waveform for scrolling and navigation
Hover Show a vertical line and elapsed-time label that follows the mouse cursor
Zoom Zoom in and out with the scroll wheel or a pinch gesture
Record Record audio directly from the microphone and render it as a waveform
Envelope Draw a volume-automation curve over the waveform with draggable points