# Get Started
This guide will walk you through adding **svelte-audio-ui** components using the [shadcn-svelte](https://shadcn-svelte.com) CLI and registry system. ## Prerequisites Before you begin, make sure you have: - A **Svelte 5 project** (SvelteKit recommended for most use cases) - **Tailwind CSS v4** properly configured - **shadcn-svelte** initialized in your project If you haven’t initialized shadcn-svelte yet, run: ## Adding Components You can add components **svelte-audio-ui** using **shadcn-svelte** CLI or **manually by copying the files.** {#snippet cli()} This command will: - add the `AudioPlayer` component - automatically install required shadcn primitives - include the audio store and core logic - install the `AudioProvider` if it does not already exist Everything is copied into your project—nothing is installed as a runtime dependency. {/snippet} {#snippet manual()} > On Progress {/snippet} ## Step 3: Setup AudioProvider The `AudioProvider` is required and will be added automatically when installing your first audio component. It acts as the central engine that: - initializes and manages the HTMLAudioElement - syncs playback state with the store - handles buffering, retries, and errors - preloads upcoming tracks for smoother playback - persists playback state (volume, progress, queue, etc) Wrap your app with `AudioProvider` at the root level: ```svelte {@render children()} ``` This ensures all audio components share a single, consistent playback state. ## Step 4: Use the component ```svelte {@render children()} ``` ## Styling Components are styled with a design token system defined by CSS variables and implemented with Tailwind CSS. The variables follow the same approach as shadcn/ui and are fully customizable. For detailed information about styling, color tokens, and customization options, see the [shadcn-svelte theming documentation.](https://www.shadcn-svelte.com/docs/theming) ## Working with LLMs I try to keep the documentation structured in a way that’s easy for AI to read and work with. To support that, I include: - **[llms.txt](/llms.txt)** — a lightweight map of the documentation and component structure, so AI tools can quickly understand how things are organized without scanning everything. - **[llms-full.txt](/llms-full.txt)** — a more complete dump of the docs and component sources, useful when you want deeper analysis or more accurate generation. - **Copy Markdown button** — available on every page, so you can quickly grab the content and feed it into your own AI workflow without extra cleanup. # Introduction
**svelte-audio-ui** is a collection of audio UI components built with [Svelte](https://svelte.dev), [Tailwind CSS](https://tailwindcss.com), and on top of [shadcn-svelte](https://shadcn-svelte.com). It is inspired by [audio-ui](https://audio-ui.xyz)—an audio component system built on top of shadcn/ui for React—but rethought and rebuilt for the Svelte ecosystem. **This is not a component library. It is how you build your own audio component system.** ## Why I’ve used a lot of UI libraries over time, and they usually work well at the beginning. But once you need deeper control—like adjusting behavior, matching a design system, or building something slightly outside the provided components—things start to break down. You end up: - wrapping components just to change small behavior details - overriding styles in ways that feel fragile and hard to maintain - mixing multiple libraries that don’t share the same API or design language That friction adds up quickly. svelte-audio-ui is my attempt to solve that by keeping everything simple: > give you the actual code, not an abstraction layer ## Not a Component Library svelte-audio-ui follows the same philosophy as audio-ui and shadcn: You don’t install it as a dependency. You copy the component into your project and own it. This approach gives you: - **No Lock-in:** Your components live inside your codebase, so you are never tied to an external package or update cycle that might break your UI. - **Full Control Over Behavior:** You can change logic, structure, or state handling without needing to wrap or override anything. - **Long-Term Maintainability:** Instead of fighting abstractions, your components evolve naturally alongside your application. ## Built for Svelte 5 This project is built specifically for modern Svelte, not adapted from another framework. It uses Svelte 5 patterns and runes to keep components: - **Explicit and Predictable:** State and reactivity are easy to follow without hidden magic or complex abstractions. - **Lightweight by Default:** No unnecessary layers, just straightforward component logic that feels close to plain JavaScript. - **Easy to Extend:** Adding new features or modifying behavior does not require learning a custom API. The goal is simple: everything should feel like native Svelte code. ## Inspired by shadcn-svelte The workflow is heavily influenced by [shadcn-svelte](https://shadcn-svelte.com): - components are copied, not installed - everything lives in your project - nothing is hidden behind a package boundary svelte-audio-ui just narrows the focus into one domain: **building audio interfaces that are flexible and composable.** ## Composition Instead of shipping one large “Audio Player” component, the system is built from smaller primitives that can be combined as needed. Typical building blocks include: - **Player Controls:** Play, pause, skip, and other interaction elements designed to be reused across different layouts. - **Timeline / Progress:** A flexible progress system that can be adapted into simple sliders or more advanced scrubbing interactions. - **Volume Controls:** Independent and composable volume handling that can be reused in different contexts. - **Optional Layers (Waveform, Metadata):** Additional UI layers that can be plugged in when needed without affecting the core system. This makes the system flexible enough for both simple players and more complex audio interfaces. ## Beautiful Defaults Styling is handled with [Tailwind CSS](https://tailwindcss.com), with a focus on clean and consistent defaults. - **Minimal but Practical:** Components look good out of the box without trying to impose a heavy visual identity. - **Consistent Across Components:** Spacing, sizing, and interaction patterns are aligned so everything feels like part of the same system. - **Easy to Customize:** Because styles are local and not abstracted, you can adjust them directly without fighting specificity or overrides. ## AI-Ready Because everything is just code inside your project, AI tools can work with it more effectively. - **Readable Structure:** Components follow consistent patterns, making them easier for AI to understand. - **Extensible System:** AI can help generate new components that match your existing structure and conventions. - **Faster Iteration:** Instead of starting from scratch, you can evolve your system with AI assistance over time. ## Particles On top of primitives, there are also [particles](/particles)—pre-built compositions of multiple components. ## Open Source svelte-audio-ui is open source and built in the open. I’m working on this as an indie developer, so the project will continue to evolve as I use it in real projects. If it’s useful for you, feel free to use it, adapt it, or contribute back. # Audio Playback Speed
A compact dropdown button for switching playback speed on the fly — from a slow `0.5x` all the way up to `2x`. Shows the current rate directly on the button, auto-disables itself when a live stream is detected, and remembers your choice across page reloads.
## Installation {#snippet cli()} {/snippet} {#snippet manual()} {#if viewerData} {:else}

Source code not available.

{/if} {/snippet}
## Usage ```svelte ``` ### Basic Drop it anywhere — no extra wiring needed, it reads from and writes to `audioStore` directly: ```svelte ``` ### Icon-only mode Pass `size="icon"` to hide the gauge icon and show only the speed label — handy when space is tight in a control bar: ```svelte ``` ### Custom speeds Swap out the default speed options with your own list: ```svelte ``` ## API Reference ### AudioPlaybackSpeed #### Props | Prop | Type | Default | Description | | --------- | ------------------------------------ | ----------------- | ------------------------------------------------------------------------------ | | `speeds` | `{ value: number; label: string }[]` | `DEFAULT_SPEEDS` | Speed options. Defaults: `0.5x`, `0.75x`, `1x`, `1.25x`, `1.5x`, `2x`. | | `size` | `string` | `"sm"` | Button size. Use `"icon"` to hide the gauge icon and show only the speed label.| | `variant` | `string` | `"outline"` | Button visual variant. | | `class` | `string` | - | Additional CSS classes. | Accepts any additional HTML button attributes via `...rest`. #### Behavior - **Live streams** — automatically disabled when `htmlAudio.isLive()` returns `true`. Tooltip changes to `"Not available for live streams"` so the user always knows why. - **Current speed indicator** — the active rate is shown on the button and marked with a radio checkmark in the dropdown. - **Persistence** — speed is saved to `localStorage` via `audioStore` and restored on the next page load. - **Icon mode** — when `size="icon"`, the `Gauge` icon is hidden; only the speed label (e.g. `1x`) is shown. > **Note:** `AudioPlaybackSpeed` requires `AudioProvider` (or the audio store) to be mounted higher in the tree. It reads `audioStore.playbackRate` and `audioStore.duration` reactively via Svelte 5 `$derived` runes — no hook wrappers needed. ## Examples ### Inside a player control bar ```svelte ``` ### Custom labels ```svelte ``` ## Related - [Audio Player](/docs/components/player) — the full player component system - [Audio Provider](/docs/components/provider) — required wrapper that manages playback state # Audio Player
## Installation {#snippet cli()} {/snippet} {#snippet manual()} {#if viewerData} {:else}

Source code not available.

{/if} {/snippet}
## Setup Wrap your app with `AudioProvider` at the root level. It powers everything behind the scenes—state, playback, events, retries, and preloading—so all audio components stay in sync. First, wrap your app with `AudioProvider` at the root level: ```svelte {@render children()} ``` ## Usage Use the component you need : ```svelte ``` ### Stacked Layout A player with stacked variant, showing time displays above and below the seek bar.
### Player with Queue A full-featured player with queue management, shuffle, and repeat controls. Uses `AudioPlayerControlGroup` for flexible layout management.
For more queue management options, see the [Audio Queue documentation](/docs/components/queue). ## API Reference ### AudioPlayer.Root A styled container component for audio controls. This is a presentational wrapper that provides consistent styling. All audio components are self-contained and read state from the global store. #### Props Inherits all props from `HTMLDivElement`. #### Example ```svelte {/* Your audio controls */} ``` ### AudioPlayer.ControlBar A container component that holds audio player controls. Use it to wrap your control components. #### Props | Prop | Type | Default | Description | | --------- | ------------------------ | ----------- | ----------------------------------- | | `variant` | `"compact" \| "stacked"` | `"compact"` | Layout variant for the control bar. | | `class` | `string` | - | Additional CSS classes. | #### Example ```svelte ``` #### Stacked Layout ```svelte ``` ### AudioPlayer.ControlGroup A flexible wrapper component for grouping audio controls and managing flex layouts. Useful for creating custom layouts with flex-col, justify-between, etc. #### Props | Prop | Type | Default | Description | | ------- | -------- | ------- | ----------------------- | | `class` | `string` | - | Additional CSS classes. | #### Example ```svelte ``` ### AudioPlayer.Play A button that toggles play/pause state. Shows a loading spinner when buffering or loading, and automatically handles the Space bar keyboard shortcut. #### Props | Prop | Type | Default | Description | | --------- | ------------------------- | --------- | ------------------------- | | `class` | `string` | - | Additional CSS classes. | | `size` | `string` | `"icon"` | Button size variant. | | `variant` | `string` | `"ghost"` | Button visual variant. | | `onclick` | `(e: MouseEvent) => void` | - | Additional click handler. | > **Keyboard Shortcuts**: Automatically handles the Space bar to toggle play/pause when focus is on `document.body`. ### AudioPlayer.SkipBack Navigates to the previous track. If the current track has played for more than 3 seconds, it restarts the current track instead. Accepts `class`, `size`, and `variant` props (same as `AudioPlayer.Play`). ### AudioPlayer.SkipForward Navigates to the next track in the queue. Accepts `class`, `size`, and `variant` props (same as `AudioPlayer.Play`). ### AudioPlayer.Rewind Seeks backward by 10 seconds. Disabled on live streams. Accepts `class`, `size`, and `variant` props (same as `AudioPlayer.Play`). ### AudioPlayer.FastForward Seeks forward by 10 seconds. Disabled on live streams. Accepts `class`, `size`, and `variant` props (same as `AudioPlayer.Play`). ### AudioPlayer.SeekBar A slider that shows playback progress and allows seeking. Locked and shows 100% for live streams. #### Props | Prop | Type | Default | Description | | ------- | -------- | ------- | ----------------------- | | `class` | `string` | - | Additional CSS classes. | ### AudioPlayer.TimeDisplay Displays the current playback time or remaining time. #### Props | Prop | Type | Default | Description | | ----------- | --------- | ------- | ----------------------------------------------- | | `remaining` | `boolean` | `false` | Display remaining time instead of elapsed time. | | `class` | `string` | - | Additional CSS classes. | On live streams: the non-remaining display shows elapsed time, and the remaining display shows a pulsing **LIVE** badge with a Radio icon. ### AudioPlayer.Volume A dropdown button that opens a volume slider. Includes a mute toggle button inside the dropdown. Hidden on mobile (`hidden md:flex`). #### Props | Prop | Type | Default | Description | | --------- | -------- | ----------- | ----------------------- | | `class` | `string` | - | Additional CSS classes. | | `size` | `string` | `"icon"` | Button size variant. | | `variant` | `string` | `"outline"` | Button visual variant. | ## Notes #### Important Information : - **Component Architecture:** All audio components are self-contained and read state directly from the global `audioStore` — a Svelte 5 reactive class instance (using `$state` fields) defined in `audio-store.svelte.ts`. The audio player uses the HTML5 audio element under the hood via the `htmlAudio` singleton from `html-audio.ts`. - **AudioProvider Role:** The `AudioProvider` component manages the audio element lifecycle by importing the `htmlAudio` singleton directly (no hook needed). It initialises the `HTMLAudioElement` inside `onMount`, registers all playback event listeners via an `AbortController` (automatically cleaned up on destroy), handles error retries (up to 3 retries with exponential backoff), preloads the next track into a secondary muted `