# vue-audio-visual draws audio spectrums inside Vue templates

> vue-audio-visual is a Vue 3 plugin that renders HTML5 audio as bars, lines, circles, waveforms and media visualizations on a canvas, with composable functions for full control. It is convenient for prototypes and media pages, and it is tied to the browser's Web Audio API.

**staskobzar/vue-audio-visual** — VueJS audio visualization components

- Repository: https://github.com/staskobzar/vue-audio-visual
- Stars: 802 · Forks: 112
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/staskobzar-vue-audio-visual

## Canvas visualizers bound to an audio element

vue-audio-visual is a set of Vue components that draw a visualization of an audio file. The README describes it as an audio spectrum visualizer plugin for the VueJS framework, built with the HTML5 Web Audio API and compatible with all browsers that support the HTML5 audio API.

The components are not standalone widgets that hide an audio element. Most of them take a src pointing at an audio file and create the audio element themselves, wrapped in a div, which means the markup stays as small as one tag. The simplest case is a single line element:

```ts
<av-line :line-width="2" line-color="lime" src="/static/music.mp3"></av-line>
```

That syntax is not valid TypeScript, but it is the exact template line the README uses, and it shows the shape of the API: props in kebab-case, a src attribute for the file, and styling parameters passed as plain attributes.

The audience is Vue developers who need a visual element next to a player, whether for a music page, a media site, or a demo. The plugin sits between a bare audio tag and a full visualizer built from scratch, and its value is in the middle: less code than a hand-rolled analyser, more control than a static element.

A demo page is published for working examples of each component, and the project ships no homepage beyond the repository itself.

## Five components, five matching composable functions

The component set is small and each member has a matching composable function, which is the clearest way to understand the library's structure. The API table in the README lists av-bars as AVBars with useAVBars, av-circle as AvCircle with useAVCircle, av-line as AVLine with useAVLine, av-media as AVMedia with useAVMedia, and av-waveform as AVWaveform with useAVWaveform.

Each renders a different visual form. av-bars draws a frequency bar chart and accepts a bar colour that can be an array, which is how the README's example produces a gradient across bars, along with separate colours for the caps on top of each bar, a canvas fill colour and a cap height. av-circle draws a radial meter with configurable outline and progress widths, an outline meter space, and an optional playtime readout rendered in a given font size and family. av-line draws the spectrum as a stroked line. av-waveform is different in kind: it pre-loads the audio content and generates a clickable waveform, so seeking is done by clicking the rendered shape.

av-media is the odd one out because it is not driven by a file URL. It takes a media object and a type, for example type="vbar", and the README notes there are more media types than that one. A media object is presumably something the surrounding application holds, such as a video or stream, rather than a static mp3 the component fetches.

The naming inconsistency is worth flagging. av-circle is documented as AvCircle while the others use an uppercase second letter, and the composable names are all useAV prefixed. That will not break anything, but it will cost you a moment when you are looking up the right symbol.

## Install the plugin or import a single component

The package is installed from npm:

```bash
npm install --save vue-audio-visual
```

There are then two ways to wire it up. The plugin route registers everything globally, which is what the README calls the plugin, in the application's main.js:

```ts
import { createApp } from "vue";
import App from "./App.vue";
import { AVPlugin } from "vue-audio-visual";

const app = createApp(App);
app.use(AVPlugin);

app.mount("#app");
```

After that, any component is available in any template without a further import, and the README shows the resulting markup as a single av-bars element with a src and a bar color.

The second route skips the plugin. A single component is imported and used directly, which keeps the bundle smaller when you only need one visualizer. The README's example does this with the waveform component in a script setup block:

```ts
import { AVWaveform } from 'vue-audio-visual'
```

The package manifest shows why both routes exist. The main entry is a UMD build, the module field points at an ES module build, and the types field points at generated declaration files, with exports mapped so that import and require resolve to different builds.

The declared runtime dependencies are small: vue at ^3.5.30 and @vueuse/core at ^14.2.1. The component code is written in TypeScript, and the build pipeline in the package scripts runs type checking, the demo build, the distributable build and the type build as separate steps.

## Composable functions hand you the audio and canvas refs

Every component is built on a composable function, and each component uses its composable internally. That internal structure is exposed, which is the feature that turns the library from a fixed widget into a building block.

The composables take the audio element ref and the canvas ref directly, so you can drive the visualization from your own markup rather than from the component's props:

```ts
import { ref } from 'vue'
import { useAVBars } from 'vue-audio-visual'

const player = ref(null)
const canvas = ref(null)
const mySource = "./symphony.mp3"

useAVBars(player, canvas, { src: mySource, canvHeight: 40, canvWidth: 200, barColor: 'lime' })
```

The template that goes with it declares the audio element with the ref and a canvas element with the other ref, and the composable then wires the two together and renders into the canvas you control.

The README describes the composables as handy when you need full access to the audio or canvas elements. That is the honest reason to use them: you need the element to exist in your own template, because you want to place it, style it, or attach your own behaviour to it.

The cost is that you now own the element lifecycle. With the component route, the component creates the audio element inside a div when a src is provided, as the common props table describes. With the composable route, that wiring is your responsibility, including the case where your audio source changes after mount.

## Kebab-case props in templates, camelCase in composable options

The prop conventions are documented with a small rule that saves a lot of guesswork. Props that follow Vue naming conventions are written in kebab-case in a template, and when the same prop is passed to a composable function the name is expected in camelCase, so a prop named foo-bar becomes the parameter fooBar.

This is a deliberate bridge between two conventions rather than an inconsistency. In a template, Vue passes attributes as strings and long names are conventionally hyphenated; in JavaScript options objects, camelCase is the natural spelling. Supporting both means the composable options read like normal JavaScript while the templates stay idiomatic.

The props themselves come in two groups. There are common props shared by all components and specific props for each component, and the README documents them separately: common props cover src, which takes a URL for the audio element's src attribute and defaults to null, and audio-controls, a Boolean that defaults to true and controls whether the audio element is displayed with its controls attribute.

The per-component tables are where the design lives, since av-line, av-bars, av-circle, av-waveform and av-media each have their own set. The README's own examples hint at the scale: av-bars alone takes a bar colour that may be an array, a caps colour, a canvas fill colour, a cap height and a src, and av-circle adds an outline width, a progress width, an outline meter space, a playtime flag and a playtime font. The library is opinionated about the visual vocabulary and configurable about the details.

## Vue 2 users are pinned to an old plugin version

The version split is the sharpest constraint in the project and it is flagged as a warning at the top of the README. The current plugin version is compatible only with Vue 3, and for Vue 2 the instruction is to use plugin version 2.5.1:

```bash
npm i -S vue-audio-visual@2.5.1
```

So there are two lines of development with different capabilities, and a Vue 2 project cannot simply upgrade. The manifest confirms the current line is Vue 3 based, with vue declared as a dependency at ^3.5.30, and the package version itself is 3.1.1.

The repository structure backs up the impression of an active TypeScript rewrite rather than a legacy code base with a new coat of paint. There are separate tsconfig files for the app, the build types, the eslint configuration and the vitest configuration, a vite.config.ts alongside a vite.config.dist.ts for the distributable build, an eslint.config.cjs, and a tests.setup.ts file. Tests run on vitest with a jsdom environment, and the coverage variant is wired into the test:ci script. The devDependencies list includes @vue/test-utils and @vitest/coverage-v8, so component tests are part of the toolchain rather than an afterthought.

The maintenance picture is consistent with that. The repository is not archived, the last push was on 2026-10-13, and the tagged releases are v3.1.1 on 2026-06-14, v3.1.0 on 2026-03-21 and v3.0.11 on 2025-03-26, which is a steady release cadence for a component library.

## Where the canvas approach runs out of road

The limits are technical and worth stating before you build a page around these components.

The first is the browser. Everything is built on the HTML5 audio API and the Web Audio API, so the visualizer only works where those are available. There is no server-side fallback, and the README does not describe how these components behave during server-side rendering, where an audio element and a canvas do not exist yet. A project that renders on the server needs to handle that case itself.

The second is av-waveform. It pre-loads the audio content and then generates a clickable waveform, which means the client fetches the whole file before it can draw the shape. For a long track, or a large file served to mobile, that is a real cost, and there is no peak-data format described in the documentation that would let the waveform be drawn from a small summary file.

The third is the audio element model. Components are built around an audio element with a src, so anything that streams, plays a blob, or comes from a MediaStream needs the composable route and manual wiring.

The fourth is that the library draws a spectrum, not a designed visualization. The visual vocabulary is a handful of chart forms with colour and width props. If you need a custom visual, you are back to the canvas and the Web Audio API by hand.

## The hand-written analyser alternative

The alternative to this plugin is not another package so much as the platform itself. A working visualizer is short: create an AudioContext, create a MediaElementAudioSourceNode from your audio element, connect an AnalyserNode to it, read the frequency data on each animation frame, and draw bars onto a canvas. That is a few dozen lines, and you keep the whole graph under your control.

The difference in approach is where the code lives. With vue-audio-visual, the analyser, the drawing loop, the resize handling and the audio element creation are the library's job, and you configure the result through props. With the hand-written version, all of that is your job, and in exchange you can share one analyser between several canvases, react to frequency data in application logic, draw something the library has no component for, or use a source that is not a plain file.

The practical split is between presets and control. If you want a bar chart that looks a certain way in an afternoon, the plugin is the shorter path, and the props tables plus the composable escape hatch mean you are not locked in. If the visualization is the point of the page rather than an accessory, writing it against the Web Audio API directly gives you more room and one fewer dependency.

Note that the plugin itself leans on @vueuse/core rather than reinventing browser state handling, so the hand-written route is not as bare as it sounds.

## Conclusion

Adopt vue-audio-visual for Vue 3 applications that need an audio visualizer quickly and want the visual style configured through props rather than hand-written canvas code. Do not choose it for Vue 2 projects beyond the pinned 2.5.1 release, for server-rendered pages, or for applications that need sample-accurate waveform peaks without downloading the whole file. Verify first that the browsers you target support the HTML5 audio API, and read the props tables for av-line, av-bars, av-circle, av-waveform and av-media before committing to a look. The last push was on 2026-10-13 and the current package version is 3.1.1.

## FAQ

### How do I install vue-audio-visual for Vue 3?

Run npm install --save vue-audio-visual, then register the plugin in main.js with app.use(AVPlugin) after importing { AVPlugin } from "vue-audio-visual". Components such as av-bars can then be used in any template.

### Does vue-audio-visual work with Vue 2?

Only through the older release. The README warns that the current plugin version is compatible only with Vue 3, and for Vue 2 you should install version 2.5.1 with npm i -S vue-audio-visual@2.5.1.

### What is the difference between a component and a composable function in vue-audio-visual?

Each component is built on a matching composable such as useAVBars, and the composable takes the audio element ref and the canvas ref so you can supply your own markup and have full access to those elements. Prop names also change style, kebab-case in a template and camelCase in composable options.

### Which visualization components does vue-audio-visual provide?

The API table lists av-bars, av-circle, av-line, av-media and av-waveform, each with a matching composable function useAVBars, useAVCircle, useAVLine, useAVMedia and useAVWaveform.

### What licence is vue-audio-visual released under?

MIT. The package manifest declares the MIT licence and the LICENSE file at the repository root holds the text. The current package version is 3.1.1, with v3.1.1 released on 2026-06-14 and the last push on 2026-10-13.

## Sources

- [Issues](https://github.com/staskobzar/vue-audio-visual/issues)
- [License: MIT](https://github.com/staskobzar/vue-audio-visual/blob/master/LICENSE)
- [README](https://github.com/staskobzar/vue-audio-visual/blob/master/README.md)
- [Releases](https://github.com/staskobzar/vue-audio-visual/releases)
- [staskobzar/vue-audio-visual on GitHub](https://github.com/staskobzar/vue-audio-visual)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/staskobzar-vue-audio-visual
