audiocn-svelte
Esc

Start typing to search the docs

useFrameSource

Subscribe a callback to a frame source, with automatic cleanup.

1 min read · 134 words

Every audiocn-svelte meter and visualizer uses this hook for its source prop. Use it to build your own components on any frame source.

$ pnpm dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-frame-source.json

Usage

<script lang="ts">
	import { useFrameSource } from "#lib/hooks/use-frame-source.svelte.js";
	import { dbToLevel } from "#lib/audio/decibels.js";
	import type { FrameSource, MeterFrame } from "#lib/audio/types.js";

	let { source }: { source: FrameSource<MeterFrame> } = $props();

	let bar = $state<HTMLDivElement | null>(null);

	useFrameSource(
		() => source,
		(frame) => {
			const level = dbToLevel(frame.channels[0]?.peakDb ?? -Infinity);
			bar?.style.setProperty("--level", String(level));
		}
	);
</script>

<div class="h-2 w-40 rounded-full bg-muted">
	<div bind:this={bar} class="h-full origin-left scale-x-(--level) rounded-full bg-primary"></div>
</div>

The callback runs outside Svelte's reactivity, so it can update the DOM on every frame without touching state. Call the hook during component setup, and pass the source as a getter, () => source, so a new source resubscribes.

API

PropTypeDefault
source

The source to subscribe to. Changing it resubscribes.

MaybeGetter<FrameSource<T> | null | undefined>—
onFrame

Called for every frame. It sees current props, so it never causes a resubscribe.

(frame: T) => void—
options.enabled

Pause the subscription without unmounting.

booleantrue

options can be an object or a getter, such as () => ({ enabled }).

Last updated on October 7, 2026