Building a Composable Audio Player: My Journey in Web Audio Development
My Story
I'm a developer passionate about audio and the web. During the week, I code. On weekends, I produce music. These two worlds remained separate for me for a long time, until the day I decided to bring them together.
The Spark
It all started when I wanted to share my music with my loved ones. I was producing tracks in my home studio, but sharing was always complicated. Existing platforms didn't really meet my needs. I wanted something that could:
- Showcase my music
- Be simple for non-technical people
- Stay personal and authentic
- Work perfectly on all devices
From Ouest Audio to audio/ui
I started building Ouest Audio, a complete music streaming application.
The Evolution
Ouest Audio became a complex application with features like:
- Playlists and queue management
- Next/previous track controls
- Shuffle playback
- Multiple audio sources
While these features are excellent for a complete streaming app, I realized that many developers mainly needed a solid foundation for audio playback. That's when I decided to extract the core audio functionality into a separate, composable component registry — audio/ui.
User Feedback That Shaped audio/ui
I shared early versions with my musician friends, and their feedback was invaluable:
- "The player is heavy on mobile"
- "Why can't I easily share a specific track?"
- "I'd like to customize the player for my own music"
- "I need to manage my playlists"
The Composable Approach
Rather than building yet another monolithic audio player, I focused on something more flexible. My goal was to make audio development as simple as assembling React components, while leaving the freedom to:
- Choose only what you need
- Customize every piece
- Own your code
- Build your way
In the philosophy of shadcn, audio/ui is a component registry designed to be copied into your project rather than installed as a dependency. This approach gives you total control over the code and style, making customization and maintenance easier.
Breaking Down the Components
Here's how I built each piece.
The Complete Player
Available Components
The player above is composed of several components that work together:
Playback Controls
AudioPlayerPlay: Play/pause with keyboard shortcut (spacebar)AudioPlayerSkipBack/AudioPlayerSkipForward: Navigation between tracksAudioPlayerRewind/AudioPlayerFastForward: Rewind/forward by 10 seconds
Progress Bar
AudioPlayerSeekBar: Progress bar with buffer supportAudioPlayerTimeDisplay: Display current or remaining time- Smooth drag-and-drop and real-time updates
Queue Management
AudioTrackList: Track list with search, sort, and drag-and-dropAudioQueue: Queue management dialog with searchAudioQueueShuffle/AudioQueueRepeatMode: Shuffle and repeat playback controlsAudioQueuePreferences: Compact menu with all queue settings
Volume
AudioPlayerVolume: Volume control with dropdown menu- Quick mute toggle and visual feedback
Installation and Usage
To add audio/ui components to your project, simply use the Shadcn CLI:
This command will automatically copy the component source code and its dependencies into your project.
AudioProvider Configuration
The AudioProvider initializes the audio element, handles playback events, retries on error, preloads next tracks, and synchronizes audio state with the Zustand store.
Wrap your application with AudioProvider at the root level:
import { AudioProvider } from "@/components/audio/provider";
export default function RootLayout({ children }) {
return (
<AudioProvider tracks={initialTracks}>{children}</AudioProvider>
);
}Basic Usage
import {
AudioPlayer,
AudioPlayerControlBar,
AudioPlayerPlay,
} from "@/components/audio/player";
export function MyAudioPlayer() {
return (
<AudioPlayer>
<AudioPlayerControlBar>
<AudioPlayerPlay />
</AudioPlayerControlBar>
</AudioPlayer>
);
}Complete Player with Queue
Here's an example of a complete player with all features:
Customization
Since the code is copied directly into your project, you can freely modify the source files according to your needs. Adapt styles, change behavior, or extend functionality.
Key Features
Queue Management
audio/ui includes a complete queue management system:
- Queue: Add, remove, and reorganize tracks
- Search: Filter tracks by title or artist
- Sort: Reorganize by drag-and-drop
- Insertion Modes: Choose where to add (beginning, end, after current track)
Playback Modes
- Shuffle: Shuffle the queue
- Repeat: Three modes available (none, one track, entire queue)
- Navigation: Next/previous track controls with smart logic
Store and State
The system uses Zustand with automatic localStorage persistence for playback state, queue, history, and user preferences.
Lessons Learned
Technical Points
- The Web Audio API is powerful but complex
- Browser compatibility is an ongoing battle
- Zustand proved to be an excellent choice for state management
- Performance optimization requires granular selectors
Common Challenges
- Resources must be properly cleaned up
- Browser autoplay policies are strict
- Audio context can be suspended
- Error states must be properly handled
- Queue management with shuffle and repeat requires complex logic
Best Practices
- Keep an API simple and intuitive
- TypeScript is your ally
- Error handling is essential
- Mobile-first is the way to go
- Accessibility is not optional
What's Next
This project was an opportunity to bring together my two passions: music and development. Over the past two years, I've spent more time coding than producing music, but the lessons learned from both worlds have been invaluable.
Current State of audio/ui
audio/ui is now a complete component registry that includes:
- Audio Player: Composable audio player with all controls
- Audio Queue: Complete queue management system with search and sort
- Audio Track: Track display and management components
- Audio Store: Zustand store with localStorage persistence
- Audio Library: Singleton
$audiofor playback management - Extended UI Components: Slider with buffer, Sortable List, etc.
What's Coming
I continue to improve and extend audio/ui with additional audio components, advanced features, audio visualizations (waveforms, spectrum analyzers), and enriched documentation.
Resources
- audio/ui — Component registry and documentation
- GitHub Repository — Contributions welcome!