---
title: "API reference"
description: "The FFTVisualizer class — constructor, getters, methods, events, and helpers."
canonical_url: "https://www.fftvisualizer.com/core/api"
---
# API reference

> The FFTVisualizer class — constructor, getters, methods, events, and helpers.

`@fft-visualizer/core` exports the imperative `FFTVisualizer` class plus a `parseCssColor`
helper. All configuration uses the shared option set documented in [Options](https://www.fftvisualizer.com/guide/options).

## Constructor

```ts
import { FFTVisualizer, type FFTVisualizerOptions } from '@fft-visualizer/core'

const viz = new FFTVisualizer(canvas, options)
```

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        canvas
      </code>
    </td>
    
    <td>
      <code>
        HTMLCanvasElement
      </code>
    </td>
    
    <td>
      The canvas to render into. The visualizer sizes to the canvas's <strong>
        parent element
      </strong>
      
       and observes it for resizes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        options
      </code>
    </td>
    
    <td>
      <code>
        FFTVisualizerOptions
      </code>
      
       <em>
        (optional)
      </em>
    </td>
    
    <td>
      Any of the <a href="https://www.fftvisualizer.com/guide/options">
        shared options
      </a>
    </td>
  </tr>
</tbody>
</table>

Constructing the instance initializes WebGL and **connects immediately** using `options.mode`
(local capture starts, a WebSocket opens, or external mode begins rendering). If WebGL fails
to initialize, an `error` event is emitted instead.

## Getters

<table>
<thead>
  <tr>
    <th>
      Getter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        isConnected
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      Whether the data source is currently active
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fps
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      Frames processed in the last second
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        audioDevices
      </code>
    </td>
    
    <td>
      <code>
        AudioDevice[]
      </code>
    </td>
    
    <td>
      Known audio input devices (populated after <code>
        getAudioDevices()
      </code>
      
       or local capture)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        activeAudioDeviceId
      </code>
    </td>
    
    <td>
      <code>
        string | undefined
      </code>
    </td>
    
    <td>
      The device ID currently in use for local mic capture
    </td>
  </tr>
</tbody>
</table>

## Methods

<table>
<thead>
  <tr>
    <th>
      Method
    </th>
    
    <th>
      Signature
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        connect
      </code>
    </td>
    
    <td>
      <code>
        () => void
      </code>
    </td>
    
    <td>
      Start the current <code>
        mode
      </code>
      
       (open the WebSocket, start capture, or begin external rendering). Called automatically by the constructor
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        disconnect
      </code>
    </td>
    
    <td>
      <code>
        () => void
      </code>
    </td>
    
    <td>
      Stop the data source and rendering
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        setOptions
      </code>
    </td>
    
    <td>
      <code>
        (patch: Partial<FFTVisualizerOptions>) => void
      </code>
    </td>
    
    <td>
      Apply a partial options update at runtime (see below)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        feedData
      </code>
    </td>
    
    <td>
      <code>
        (data: Uint8Array, left?: Uint8Array, right?: Uint8Array) => void
      </code>
    </td>
    
    <td>
      Feed FFT magnitudes (0–255) in <code>
        external
      </code>
      
       mode. The data is <strong>
        copied
      </strong>
      
      , so reusing one buffer per frame is safe. Pass <code>
        left
      </code>
      
       and <code>
        right
      </code>
      
       for stereo
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        refreshGradient
      </code>
    </td>
    
    <td>
      <code>
        () => void
      </code>
    </td>
    
    <td>
      Rebuild the gradient LUT after mutating custom stops <strong>
        in place
      </strong>
      
       (not needed when you assign a new <code>
        gradient
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getAudioDevices
      </code>
    </td>
    
    <td>
      <code>
        () => Promise<AudioDevice[]>
      </code>
    </td>
    
    <td>
      Enumerate audio input devices (prompts for mic permission if needed)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        destroy
      </code>
    </td>
    
    <td>
      <code>
        () => void
      </code>
    </td>
    
    <td>
      Disconnect, stop observing resize, remove all listeners, and free every WebGL resource
    </td>
  </tr>
</tbody>
</table>

### `setOptions(patch)`

Only keys whose value actually changed take effect. Changing `mode` or `websocketUrl`
reconnects; changing `bands` reallocates buffers; changing `background` or `gradient` reuploads
the relevant texture. To reload a gradient whose stops you mutated in place, either pass a new
`gradient` reference or call `refreshGradient()`.

```ts
viz.setOptions({ ledBars: true, gradient: 'sunset', bands: 20 })
```

## Events

Subscribe with `on()`, which returns an unsubscribe function; or remove a handler with `off()`.

```ts
const stop = viz.on('frame', ({ data, left, right }) => {
  // data: Uint8Array — one 0–255 magnitude per bar (length = bands)
  // left / right: per-channel arrays in stereo mode, else null
})
stop() // unsubscribe
```

<table>
<thead>
  <tr>
    <th>
      Event
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Fires when
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        connected
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      The data source became active
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        disconnected
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      The data source stopped
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        error
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      A WebSocket error, capture failure, or WebGL init failure
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        frame
      </code>
    </td>
    
    <td>
      <code>
        FrameEvent
      </code>
    </td>
    
    <td>
      Once per processed audio frame, with the display bar magnitudes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        audiostate
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Local-audio state changed (capture started/stopped, or the device list updated)
    </td>
  </tr>
</tbody>
</table>

The `frame` event is a ready-made feed for external hardware (LED strips, flip-dot displays)
— it hands you exactly what the shader draws, without re-implementing any FFT. It's
listener-gated, so it costs nothing when no handler is attached.

```ts
interface FrameEvent {
  data: Uint8Array          // per-bar magnitudes (in stereo, the per-bar max of both channels)
  left: Uint8Array | null   // per-channel in stereo, else null
  right: Uint8Array | null
}
```

## `parseCssColor(color)`

```ts
import { parseCssColor } from '@fft-visualizer/core'

parseCssColor('rgba(10, 10, 10, 0.5)') // => [r, g, b, a] normalized 0–1
```

Parses any CSS color (including `rgba()` and `'transparent'`) into a normalized `[r, g, b, a]`
tuple via a 1×1 canvas — the same routine the visualizer uses for the `background` option.

## Types

`VisualizerMode` (`'websocket' | 'local' | 'external'`), `BandCount` (`10 | 20 | 40 | 80`),
`FFTVisualizerOptions`, `FFTVisualizerEventMap`, and `FrameEvent` are all exported for typing
your own code.


## Sitemap

See the full [sitemap](https://www.fftvisualizer.com/sitemap.md) for all pages.
