<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: self-dev</title>
    <description>The latest articles on DEV Community by self-dev (@ddtamn).</description>
    <link>https://dev.to/ddtamn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1409685%2F11676a40-d23c-49cc-b236-d90916c017d2.jpeg</url>
      <title>DEV Community: self-dev</title>
      <link>https://dev.to/ddtamn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ddtamn"/>
    <language>en</language>
    <item>
      <title>I Ported audio-ui (shadcn / React) to Svelte — Here’s What I Learned</title>
      <dc:creator>self-dev</dc:creator>
      <pubDate>Wed, 01 Apr 2026 06:07:12 +0000</pubDate>
      <link>https://dev.to/ddtamn/i-ported-audio-ui-shadcn-react-to-svelte-heres-what-i-learned-5de7</link>
      <guid>https://dev.to/ddtamn/i-ported-audio-ui-shadcn-react-to-svelte-heres-what-i-learned-5de7</guid>
      <description>&lt;p&gt;Recently, I’ve been exploring how far the &lt;strong&gt;headless + composable UI philosophy&lt;/strong&gt; can go outside the React ecosystem.&lt;/p&gt;

&lt;p&gt;So I decided to take on a small challenge:&lt;br&gt;
👉 porting &lt;strong&gt;audio-ui&lt;/strong&gt; (originally built for shadcn / React) into Svelte.&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://svelte-audio-ui.vercel.app/" rel="noopener noreferrer"&gt;svelte-audio-ui&lt;/a&gt;&lt;br&gt;
Github : &lt;a href="https://github.com/ddtamn/svelte-audio-ui" rel="noopener noreferrer"&gt;github.com/ddtamn/svelte-audio-ui&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Exists
&lt;/h2&gt;

&lt;p&gt;In the React world, tools like shadcn have made it very natural to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copy components directly into your codebase&lt;/li&gt;
&lt;li&gt;fully control the implementation&lt;/li&gt;
&lt;li&gt;build systems that are easy to extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in Svelte, especially for &lt;strong&gt;audio-related UI&lt;/strong&gt;, there aren’t many solutions that follow this approach.&lt;/p&gt;

&lt;p&gt;Most libraries are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;too opinionated&lt;/li&gt;
&lt;li&gt;not composable&lt;/li&gt;
&lt;li&gt;or difficult to extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the goal here is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bring the same &lt;em&gt;“you own the code”&lt;/em&gt; philosophy into Svelte, specifically for audio UI.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Core Idea
&lt;/h2&gt;

&lt;p&gt;Instead of shipping a package, this approach follows the same pattern as shadcn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No npm dependency&lt;/li&gt;
&lt;li&gt;Components are installed into your project&lt;/li&gt;
&lt;li&gt;You can modify everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the center of it is:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;AudioProvider&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This acts as the core engine that handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;playback state&lt;/li&gt;
&lt;li&gt;queue management&lt;/li&gt;
&lt;li&gt;synchronization between components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else — player, controls, sliders — composes on top of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;AudioPlayer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/components/ui/audio/player&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;AudioPlayer.Root&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;AudioPlayer.ControlBar&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AudioPlayer.Play&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AudioPlayer.SeekBar&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AudioPlayer.Volume&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/AudioPlayer.ControlBar&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/AudioPlayer.Root&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;swap components easily&lt;/li&gt;
&lt;li&gt;extend behavior&lt;/li&gt;
&lt;li&gt;or build your own UI layer entirely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Built for the Svelte Way
&lt;/h2&gt;

&lt;p&gt;Porting wasn’t about copying code.&lt;/p&gt;

&lt;p&gt;The goal was to make it feel &lt;strong&gt;idiomatic in Svelte&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;leveraging reactivity instead of hooks&lt;/li&gt;
&lt;li&gt;simplifying state flow&lt;/li&gt;
&lt;li&gt;keeping components lightweight&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  AI-Ready Documentation
&lt;/h2&gt;

&lt;p&gt;One interesting aspect of this project is how it works with AI tools.&lt;/p&gt;

&lt;p&gt;Since everything lives inside your codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structure is predictable&lt;/li&gt;
&lt;li&gt;patterns are consistent&lt;/li&gt;
&lt;li&gt;components are easy to extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The docs also include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llms-full.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it easier for AI tools to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understand the system&lt;/li&gt;
&lt;li&gt;generate new components&lt;/li&gt;
&lt;li&gt;help you iterate faster&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extras: Particles
&lt;/h2&gt;

&lt;p&gt;There’s also a &lt;strong&gt;particles section&lt;/strong&gt; for visual experiments.&lt;/p&gt;

&lt;p&gt;It’s not core to the system, but it’s fun to explore and can be used for landing pages or creative UI.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;This is still early.&lt;/p&gt;

&lt;p&gt;Next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;refine API to feel more “Svelte-native”&lt;/li&gt;
&lt;li&gt;improve developer experience&lt;/li&gt;
&lt;li&gt;add more components as needed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Open source is interesting like this.&lt;/p&gt;

&lt;p&gt;You don’t always need to reinvent ideas — sometimes you just need to &lt;strong&gt;translate them properly into another ecosystem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you’re using Svelte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;would this be useful for you?&lt;/li&gt;
&lt;li&gt;what kind of audio components do you usually need?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to hear your thoughts 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>svelte</category>
      <category>shadcn</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
