<?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: Elle</title>
    <description>The latest articles on DEV Community by Elle (@elle001923).</description>
    <link>https://dev.to/elle001923</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%2F3803775%2F92136681-95a0-47d2-8bbf-00f705cc201c.png</url>
      <title>DEV Community: Elle</title>
      <link>https://dev.to/elle001923</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elle001923"/>
    <language>en</language>
    <item>
      <title>3 Node.js Bugs That Silently Corrupt Your Binary Data</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Mon, 16 Mar 2026 07:08:34 +0000</pubDate>
      <link>https://dev.to/elle001923/3-nodejs-bugs-that-silently-corrupt-your-binary-data-48ah</link>
      <guid>https://dev.to/elle001923/3-nodejs-bugs-that-silently-corrupt-your-binary-data-48ah</guid>
      <description>&lt;p&gt;Binary data in Node.js looks easy until it isn't. I spent a combined 6 hours debugging three bugs that all had the same root cause: treating binary data like strings.&lt;/p&gt;

&lt;p&gt;If you're calling external APIs that return audio, images, or video — read this before you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug #1: String concatenation destroys audio files
&lt;/h2&gt;

&lt;p&gt;This looks fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.mp3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file saves. It has the right size. But it won't play.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; &lt;code&gt;.toString()&lt;/code&gt; defaults to UTF-8 encoding. Binary bytes that aren't valid UTF-8 get replaced with &lt;code&gt;�&lt;/code&gt; (U+FFFD). Your audio file is now full of replacement characters where real data used to be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.mp3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep everything as Buffers. Never &lt;code&gt;.toString()&lt;/code&gt; binary data.&lt;/p&gt;

&lt;p&gt;The frustrating part: the file size looks correct, &lt;code&gt;fs.statSync&lt;/code&gt; shows something reasonable, and the first few bytes might even be valid. The corruption is scattered through the middle of the file wherever multi-byte sequences happen to be invalid UTF-8.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug #2: &lt;code&gt;response.body&lt;/code&gt; isn't what you think in fetch()
&lt;/h2&gt;

&lt;p&gt;If you migrated from &lt;code&gt;https.request&lt;/code&gt; to &lt;code&gt;fetch()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// ❌ deprecated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Node 18+, &lt;code&gt;res.buffer()&lt;/code&gt; is gone. You might reach for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Same UTF-8 corruption&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same bug as #1 — round-tripping through a string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;arrayBuffer()&lt;/code&gt; gives you the raw bytes. No encoding involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug #3: Checking binary responses with truthiness
&lt;/h2&gt;

&lt;p&gt;After calling a TTS API, you might validate the response like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TTS failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;speech.mp3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem: an empty Buffer (&lt;code&gt;Buffer.alloc(0)&lt;/code&gt;) is truthy in JavaScript. So is a Buffer containing an error message like &lt;code&gt;{"error": "quota exceeded"}&lt;/code&gt;. Both pass your check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If it's tiny, it's probably an error message, not audio&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maybeError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;?.()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;empty response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`TTS failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;maybeError&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the type AND the size. A valid audio file for even a short sentence will be several KB at minimum. Anything under 1KB is almost certainly an error response, not audio.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern
&lt;/h2&gt;

&lt;p&gt;All three bugs share the same root cause: &lt;strong&gt;binary data passing through a text layer&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Binary → String → Binary = corrupted
Binary → Buffer → Binary = safe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audio from TTS APIs&lt;/li&gt;
&lt;li&gt;Images from generation APIs&lt;/li&gt;
&lt;li&gt;Video clips from AI video services&lt;/li&gt;
&lt;li&gt;Any file downloaded over HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your API integration works for text but produces corrupt files for binary data — check whether a string is sneaking into your data pipeline. It almost always is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick checklist
&lt;/h2&gt;

&lt;p&gt;Before you ship any binary API integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Are you using &lt;code&gt;Buffer.concat()&lt;/code&gt;, not string concatenation?&lt;/li&gt;
&lt;li&gt;[ ] Are you using &lt;code&gt;res.arrayBuffer()&lt;/code&gt;, not &lt;code&gt;res.text()&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;[ ] Are you checking &lt;code&gt;Buffer.isBuffer()&lt;/code&gt; AND &lt;code&gt;.length&lt;/code&gt;, not just truthiness?&lt;/li&gt;
&lt;li&gt;[ ] Are you never calling &lt;code&gt;.toString()&lt;/code&gt; on response data before writing to disk?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are boring bugs. They don't throw errors. They produce files that look right but aren't. That's what makes them dangerous.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this useful? I write about the weird bugs I hit while building automated pipelines with Node.js. Follow for more war stories.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a Complete SaaS in 45 Minutes Using Only AI + One API</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Sun, 15 Mar 2026 14:48:59 +0000</pubDate>
      <link>https://dev.to/elle001923/i-built-a-complete-saas-in-45-minutes-using-only-ai-one-api-1oe2</link>
      <guid>https://dev.to/elle001923/i-built-a-complete-saas-in-45-minutes-using-only-ai-one-api-1oe2</guid>
      <description>&lt;p&gt;I want to be upfront: the "45 minutes" doesn't include the three hours I spent the night before trying to do the same thing with separate API accounts and giving up because I couldn't get OAuth to work with my Cloudflare Workers setup.&lt;/p&gt;

&lt;p&gt;The 45-minute version happened the next morning after I said "screw it" and tried doing everything through one gateway. It worked. I was annoyed it was that easy, because it meant the previous night was wasted.&lt;/p&gt;

&lt;p&gt;Here's the actual build.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I made
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;InvoiceBot&lt;/strong&gt; — a dead-simple SaaS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up with Google&lt;/li&gt;
&lt;li&gt;Type a description like "3 pages of web design at $500 each"&lt;/li&gt;
&lt;li&gt;AI generates a professional invoice&lt;/li&gt;
&lt;li&gt;Send it to your client via email&lt;/li&gt;
&lt;li&gt;Pro plan for $9/month via Stripe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not going to win any awards. But it has auth, payments, a database, AI generation, and email delivery. That's a real SaaS, not a landing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code (my coding agent)&lt;/li&gt;
&lt;li&gt;SkillBoss (everything backend: AI, database, auth, email, payments, hosting)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No AWS. No Vercel. No Firebase. No SendGrid account.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts that went fast
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Installing the skill:&lt;/strong&gt; 30 seconds. &lt;code&gt;curl -fsSL https://skillboss.co/install.sh | bash&lt;/code&gt;. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generating the frontend:&lt;/strong&gt; About 5 minutes. I told Claude Code what I wanted and it spit out React + Tailwind. The first version looked like a to-do app tutorial — generic cards, default blue, you know the type. I asked it to make it "less template-y" twice before I got something I wouldn't be embarrassed to show someone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI invoice generation:&lt;/strong&gt; This was the easy part. One API call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.heybossai.com/v1/chat/completions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SKILLBOSS_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai/gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Generate a professional HTML invoice. Include line items, subtotals, tax line, total, due date, and clean formatting. Use a neutral business style.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;
      &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GPT-4o is actually decent at generating structured HTML invoices. About 4 out of 5 times the output was usable without editing. The fifth time it would do something weird with the tax calculation or forget the due date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email delivery:&lt;/strong&gt; Two minutes. One fetch call, no SMTP configuration, no domain verification dance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy:&lt;/strong&gt; &lt;code&gt;node ./scripts/serve-build.js publish-worker ./dist --name invoicebot&lt;/code&gt;. Three minutes, including the time it took to remember the command.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts that were annoying
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stripe integration:&lt;/strong&gt; This took the longest — about 15 minutes, which doesn't sound bad until you realize it was mostly waiting. Connect Stripe account (browser flow), wait for webhook verification, debug a CORS issue that turned out to be a typo in my redirect URL. Standard Stripe stuff, not a SkillBoss problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth:&lt;/strong&gt; Claude Code generated the OAuth flow on the first try but used a deprecated Google endpoint. I caught it because the redirect gave me a 400. Fixed in about 5 minutes once I figured out what was wrong. This is the vibe coding trap — the code &lt;em&gt;looks&lt;/em&gt; right, and the error isn't obvious until runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The database schema:&lt;/strong&gt; Claude generated a perfectly functional schema, but it used &lt;code&gt;TEXT&lt;/code&gt; for the primary key IDs instead of UUIDs, and didn't add an index on &lt;code&gt;user_id&lt;/code&gt; in the invoices table. I noticed because I was actually reading the generated SQL. Most people wouldn't, and it would be fine at small scale but not great later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time breakdown (honest version)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install skill&lt;/td&gt;
&lt;td&gt;0.5 min&lt;/td&gt;
&lt;td&gt;The one easy part&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate frontend&lt;/td&gt;
&lt;td&gt;5 min&lt;/td&gt;
&lt;td&gt;Two iterations on design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database setup&lt;/td&gt;
&lt;td&gt;3 min&lt;/td&gt;
&lt;td&gt;Including fixing the schema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invoice AI feature&lt;/td&gt;
&lt;td&gt;3 min&lt;/td&gt;
&lt;td&gt;Worked first try&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email integration&lt;/td&gt;
&lt;td&gt;2 min&lt;/td&gt;
&lt;td&gt;Shockingly easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stripe payments&lt;/td&gt;
&lt;td&gt;15 min&lt;/td&gt;
&lt;td&gt;Mostly waiting + one typo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;3 min&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing + bug fixes&lt;/td&gt;
&lt;td&gt;12 min&lt;/td&gt;
&lt;td&gt;OAuth redirect, CSS tweaks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~44 min&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cost
&lt;/h2&gt;

&lt;p&gt;SkillBoss credits used: &lt;strong&gt;$0.47&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest expense was the AI generation calls during testing. I made maybe 20 test invoices while debugging the prompt. Database, hosting, and email were basically free at this volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Actually test the generated code more carefully.&lt;/strong&gt; The OAuth thing could've been a real problem if I'd shipped it without testing. Vibe coding is fast, but "fast to write" and "correct" are different things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not try to do it with separate APIs first.&lt;/strong&gt; The three hours I wasted the night before were entirely unnecessary. I was stubbornly trying to configure each service individually because that's what I was used to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add better error handling.&lt;/strong&gt; Claude Code generated zero error handling in the invoice generation function. If the API returns an error, the UI just shows a blank page. I added a try/catch after the fact, but a production app would need way more than that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest takeaway
&lt;/h2&gt;

&lt;p&gt;Building a SaaS in 45 minutes is cool but it's also kind of misleading. What I built works. It's deployed. You can use it. But "works" and "ready for real users" are separated by probably another 20-40 hours of: proper error handling, input validation, rate limiting, actual invoice PDF export (mine are HTML), mobile responsive testing, email deliverability setup, privacy policy, terms of service...&lt;/p&gt;

&lt;p&gt;The value isn't "skip all the hard parts." It's "skip the boring parts so you can find out faster whether the idea is worth the hard parts."&lt;/p&gt;

&lt;p&gt;For InvoiceBot specifically? Probably not. There are 500 invoice generators already. But I learned the workflow, and the &lt;em&gt;next&lt;/em&gt; idea I test will also take 45 minutes instead of a weekend.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've built something with this kind of speed — what did the gap between "it works" and "it's ready" look like? I keep underestimating that gap.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Stopped Paying $141/Month for AI APIs. Here's My Setup Now.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Sun, 15 Mar 2026 14:48:14 +0000</pubDate>
      <link>https://dev.to/elle001923/i-stopped-paying-141month-for-ai-apis-heres-my-setup-now-42i8</link>
      <guid>https://dev.to/elle001923/i-stopped-paying-141month-for-ai-apis-heres-my-setup-now-42i8</guid>
      <description>&lt;p&gt;I hit a breaking point last month when I tried to generate a 30-second video clip from a prompt. I already had a Replicate account, but the credits were drained. So I went to top up, forgot my password, reset it, re-entered my payment info because the card expired, and by the time I was ready to make the API call it had been 25 minutes. For one video clip.&lt;/p&gt;

&lt;p&gt;Then I looked at my subscriptions spreadsheet. (I keep one. I know.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI → $20/month&lt;/li&gt;
&lt;li&gt;Anthropic → $20/month&lt;/li&gt;
&lt;li&gt;ElevenLabs → $11/month&lt;/li&gt;
&lt;li&gt;Replicate → $50+/month&lt;/li&gt;
&lt;li&gt;AWS → $15/month&lt;/li&gt;
&lt;li&gt;SendGrid → $15/month&lt;/li&gt;
&lt;li&gt;Firecrawl → $10/month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;$141/month. Seven sets of billing credentials in my password manager. Three of them I used maybe twice last month.&lt;/p&gt;

&lt;p&gt;The ElevenLabs one especially annoyed me. I used TTS for &lt;em&gt;one&lt;/em&gt; project demo in February. Eleven bucks for two audio files. I should've just recorded myself talking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing that actually made me switch
&lt;/h2&gt;

&lt;p&gt;It wasn't a blog post or a product launch. I was pairing with Claude Code on a side project — an AI-powered meal planner — and I needed to: generate recipe descriptions (LLM), create food photos (image gen), and send a weekly email digest (email API). Three different services. Three different accounts to configure. Three different auth patterns for Claude to deal with.&lt;/p&gt;

&lt;p&gt;I'd already installed SkillBoss as a skill in Claude Code for something else. And Claude just... used it. For all three things. Same API key. I didn't have to stop and set up anything.&lt;/p&gt;

&lt;p&gt;That was the moment. Not because SkillBoss was better at any individual task — it wasn't — but because I didn't break my flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the install. It's a skill for Claude Code / Cursor / etc. One API key, pay-as-you-go credits, covers LLMs + images + video + audio + email + scraping + hosting.&lt;/p&gt;

&lt;p&gt;The API itself is just OpenAI-compatible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.heybossai.com/v1/chat/completions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SKILLBOSS_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anthropic/claude-sonnet-4-5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap the model string, hit a different provider. Nothing else changes. I've been doing this for about six weeks now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually spent
&lt;/h2&gt;

&lt;p&gt;March so far: &lt;strong&gt;$23&lt;/strong&gt;. And I've been more productive than the $141 months, because I stopped procrastinating tasks that required "setting up another API."&lt;/p&gt;

&lt;p&gt;The per-unit costs are basically the same as going direct. The savings come from not paying monthly minimums on services I barely touch. ElevenLabs charges $11/month whether I use it once or a hundred times. With SkillBoss I paid $0.90 for TTS this month. Because I only needed three audio files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it falls short
&lt;/h2&gt;

&lt;p&gt;I want to be honest about this because the "I switched to X and everything is perfect!" genre of blog posts is exhausting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model selection is smaller than OpenRouter.&lt;/strong&gt; If you need access to every obscure fine-tuned model on the market, OpenRouter has more options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No self-hosting.&lt;/strong&gt; If you need to run everything on your own infra, LiteLLM is the better choice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The docs lean toward the skill/agent workflow.&lt;/strong&gt; If you're building a traditional backend and just want REST API docs, it takes a minute to find what you need past all the Claude Code integration stuff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I haven't stress-tested it.&lt;/strong&gt; My usage is maybe 2-3k API calls a month. I have no idea how it handles 100k/day. Probably fine, but I haven't tried.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The thing I keep coming back to
&lt;/h2&gt;

&lt;p&gt;It's not really about the money. $141 vs $23 is nice, but the actual difference is: I used to avoid features that required a new API integration. "Oh, this project could use TTS? Eh, I'll skip it. Not worth setting up another account."&lt;/p&gt;

&lt;p&gt;Now I don't think about it. If the project needs TTS, it gets TTS. If it needs video, it gets video. The activation energy went from "30 minutes of account setup" to "already there."&lt;/p&gt;

&lt;p&gt;That's the part that matters more than the cost savings, honestly.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Curious what other people's AI API setups look like. Am I the only one who was drowning in API accounts, or is this a common problem? Genuinely asking.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Told Claude Code to Build and Deploy a Full-Stack AI App. It Took 8 Minutes.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Sun, 15 Mar 2026 11:38:24 +0000</pubDate>
      <link>https://dev.to/elle001923/i-told-claude-code-to-build-and-deploy-a-full-stack-ai-app-it-took-8-minutes-1nma</link>
      <guid>https://dev.to/elle001923/i-told-claude-code-to-build-and-deploy-a-full-stack-ai-app-it-took-8-minutes-1nma</guid>
      <description>&lt;p&gt;I've been experimenting with something that feels like cheating.&lt;/p&gt;

&lt;p&gt;I open my terminal. I type one sentence describing what I want. An AI agent builds the entire app — frontend, backend, database, auth, payments — and deploys it to Cloudflare Workers. I get back a live URL.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;create-react-app&lt;/code&gt;. No DevOps. No "let me configure the CI pipeline first."&lt;/p&gt;

&lt;p&gt;Here's what that actually looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Prompt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Build a SaaS app where users can upload a photo and get
an AI-generated avatar in 3 different styles. Add Google
login, Stripe checkout ($5 per generation), and deploy it."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. That's the entire specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happened Next
&lt;/h2&gt;

&lt;p&gt;Claude Code (running in my terminal) started working. Here's the sequence it followed — I didn't intervene once:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 0-2: Scaffolding&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a Cloudflare Workers project with Hono framework&lt;/li&gt;
&lt;li&gt;Set up D1 (SQLite at the edge) for user data and generation history&lt;/li&gt;
&lt;li&gt;Added R2 bucket for image storage&lt;/li&gt;
&lt;li&gt;Wired up Google OAuth with session management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Minutes 2-4: Core Feature&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built the upload endpoint&lt;/li&gt;
&lt;li&gt;Connected to an AI image generation model through a single API call&lt;/li&gt;
&lt;li&gt;Created 3 style variants (cartoon, oil painting, pixel art)&lt;/li&gt;
&lt;li&gt;Added a results page with download buttons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Minutes 4-6: Payments&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrated Stripe Checkout for one-time $5 payments&lt;/li&gt;
&lt;li&gt;Added webhook handler for payment confirmation&lt;/li&gt;
&lt;li&gt;Built credit system — pay once, generate once&lt;/li&gt;
&lt;li&gt;Created a simple pricing page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Minutes 6-8: Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ran &lt;code&gt;wrangler deploy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set up custom domain binding&lt;/li&gt;
&lt;li&gt;Returned the live URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Total: 8 minutes. Zero configuration files written by me.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Is This Possible?
&lt;/h2&gt;

&lt;p&gt;Three things make this work:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cloudflare Workers as the Runtime
&lt;/h3&gt;

&lt;p&gt;Workers run at the edge in 300+ cities. No servers to manage. No cold starts to worry about. The entire backend is a single JavaScript file that handles routes, auth, database queries, and API calls.&lt;/p&gt;

&lt;p&gt;D1 gives you SQLite without managing a database. R2 gives you object storage without S3 credentials. KV gives you key-value storage for sessions. It's the most "just works" deployment target I've found.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A Unified AI Gateway
&lt;/h3&gt;

&lt;p&gt;This is the piece that makes multi-model apps trivial. Instead of integrating separate SDKs for image generation, chat, TTS, or video — I use &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;SkillBoss&lt;/a&gt; as a single API gateway:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Image generation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;avatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.heybossai.com/v1/run&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vertex/gemini-3-pro-image-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; portrait of the person in this photo`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to add TTS to your app? Same endpoint, different model name. Need video generation? Same endpoint. Need web search? Same. The AI agent doesn't need to research which SDK to install — it just changes the model string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// All of these use the exact same apiCall() function:&lt;/span&gt;
&lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minimax/speech-01-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;voice&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;     &lt;span class="c1"&gt;// TTS&lt;/span&gt;
&lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vertex/veo-3.1-fast-generate-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// Video&lt;/span&gt;
&lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;replicate/elevenlabs/music&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;         &lt;span class="c1"&gt;// Music&lt;/span&gt;
&lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bedrock/claude-4-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;        &lt;span class="c1"&gt;// Chat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;100+ models. One API key. One billing dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. An AI Agent That Knows the Stack
&lt;/h3&gt;

&lt;p&gt;Claude Code isn't just autocompleting lines. It understands the full deployment pipeline — Cloudflare Workers, D1 schemas, R2 bindings, Stripe webhooks, OAuth flows. When I say "add payments," it doesn't ask me which payment provider or how to configure webhooks. It just does it.&lt;/p&gt;

&lt;p&gt;The combination of an agent that knows infrastructure + a unified AI backend + an edge runtime that needs zero config = apps that go from idea to live URL in minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I've Built This Way
&lt;/h2&gt;

&lt;p&gt;In the past month, using this exact workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Avatar Generator&lt;/strong&gt; — Upload photo, get styled portraits ($5/gen)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Podcast Creator&lt;/strong&gt; — Paste a blog URL, get a 2-minute AI podcast episode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thumbnail Generator&lt;/strong&gt; — Describe your YouTube video, get 4 thumbnail options&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email Drip Tool&lt;/strong&gt; — Write one email, AI adapts it for 5 audience segments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one took under 15 minutes from prompt to live URL. Each one has auth, payments (where needed), and a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part Nobody Mentions
&lt;/h2&gt;

&lt;p&gt;"But does the code actually work?" — yes, but it's not perfect first try. Here's what's honest:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What works immediately:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routing, auth flows, database schemas&lt;/li&gt;
&lt;li&gt;API integrations (especially with a unified gateway)&lt;/li&gt;
&lt;li&gt;Stripe checkout and webhook handling&lt;/li&gt;
&lt;li&gt;Deployment and DNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What sometimes needs a fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS edge cases (the agent occasionally picks the wrong Tailwind class)&lt;/li&gt;
&lt;li&gt;Error handling for rare API failures&lt;/li&gt;
&lt;li&gt;Mobile responsiveness on complex layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd say 80% of the time, the first deploy works. The other 20%, I give the agent a one-line correction like "the upload button is hidden on mobile" and it fixes it in 30 seconds.&lt;/p&gt;

&lt;p&gt;That's still dramatically faster than building from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install SkillBoss (the AI gateway)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash

&lt;span class="c"&gt;# 2. Use with Claude Code, Cursor, or Windsurf&lt;/span&gt;
&lt;span class="c"&gt;# The agent handles Cloudflare Workers deployment automatically&lt;/span&gt;

&lt;span class="c"&gt;# New accounts get $2 free credit — no subscription&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mental model shift is this: stop thinking about which APIs to integrate and start thinking about what you want the app to do. The infrastructure layer is solved.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What would you build if deployment took 8 minutes instead of 8 hours? Serious question — drop it in the comments and I might build it live.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>cloudflare</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Vibe Coding Hit a Wall. Here's What Nobody Tells You About the Backend Problem.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Sun, 15 Mar 2026 11:33:17 +0000</pubDate>
      <link>https://dev.to/elle001923/vibe-coding-hit-a-wall-heres-what-nobody-tells-you-about-the-backend-problem-198c</link>
      <guid>https://dev.to/elle001923/vibe-coding-hit-a-wall-heres-what-nobody-tells-you-about-the-backend-problem-198c</guid>
      <description>&lt;p&gt;Vibe coding is everywhere right now. Tell an AI agent to build you a full-stack app. Watch it scaffold React components, wire up API routes, deploy to the edge — all from natural language prompts.&lt;/p&gt;

&lt;p&gt;I've been doing this daily for months. And I need to tell you something uncomfortable: &lt;strong&gt;vibe coding has a backend problem that nobody talks about.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Moment Vibe Coding Breaks
&lt;/h2&gt;

&lt;p&gt;Here's the typical vibe coding experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: "Build me a landing page with a contact form"
AI Agent: *scaffolds Next.js app, adds Tailwind, creates form component*
Me: "Deploy it"
AI Agent: *deploys to Vercel/Cloudflare*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beautiful. 3 minutes. Ship it.&lt;/p&gt;

&lt;p&gt;Now try this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: "Build me an app that generates podcast episodes from blog posts"
AI Agent: "Sure! I'll need:
  - A TTS API key (ElevenLabs? OpenAI? Azure?)
  - A music generation API (Replicate? Suno?)
  - An image API for cover art (DALL-E? Flux? Midjourney?)
  - An LLM for script writing (which one? which provider?)
  - Oh, and where should I store the audio files?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suddenly you're not vibe coding anymore. You're &lt;strong&gt;managing infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem: AI Model Fragmentation
&lt;/h2&gt;

&lt;p&gt;Every interesting app in 2026 needs multiple AI capabilities. Not just text generation — but voice, video, images, music, search, and deployment. Each capability means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A different provider&lt;/li&gt;
&lt;li&gt;A different API format&lt;/li&gt;
&lt;li&gt;A different auth flow&lt;/li&gt;
&lt;li&gt;A different billing dashboard&lt;/li&gt;
&lt;li&gt;A different rate limit strategy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I counted mine last month. &lt;strong&gt;12 separate AI subscriptions.&lt;/strong&gt; $180/month before I'd written a single line of app code.&lt;/p&gt;

&lt;p&gt;And here's the thing that kills vibe coding: when your AI agent (Claude Code, Cursor, Windsurf — whatever you use) hits a task that requires calling an external AI API, it needs credentials, SDK knowledge, and error handling for that specific provider. The "just prompt and ship" magic disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Wanted
&lt;/h2&gt;

&lt;p&gt;I wanted to tell my AI agent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build an app that turns YouTube videos into podcast episodes with AI voiceover, background music, and auto-generated cover art. Deploy it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And have it just... work. No API key juggling. No SDK research. No "which provider should I use for TTS?"&lt;/p&gt;

&lt;p&gt;So I built exactly that.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Gateway. Every AI Model. Zero Config.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. One install in your terminal. Now your AI agent (Claude Code, Cursor, etc.) has access to 100+ AI models through a single API endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Text-to-Speech&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.heybossai.com/v1/run&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SKILLBOSS_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minimax/speech-01-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;voice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;male-qn-jingying&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Video Generation — same endpoint, different model&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.heybossai.com/v1/run&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SKILLBOSS_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vertex/veo-3.1-fast-generate-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A developer typing code, cinematic lighting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same endpoint. Same auth. Same response format. Just swap the model name.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Unlocks for Vibe Coding
&lt;/h2&gt;

&lt;p&gt;With a unified backend, the conversation goes back to being simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: "Build a tool that takes a blog URL, generates a 2-minute
     podcast with AI voice, adds background music, creates
     cover art, and deploys a player page."

AI Agent: *builds it in 10 minutes using SkillBoss API*
         *deploys to Cloudflare Workers*
         *returns live URL*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No interruptions asking which TTS provider. No stopping to configure API keys. The agent picks the best model for each task automatically.&lt;/p&gt;

&lt;p&gt;Here's what's available through that single endpoint:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chat / Reasoning&lt;/td&gt;
&lt;td&gt;Claude 4.5, GPT-5, Gemini 3, DeepSeek R1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Generation&lt;/td&gt;
&lt;td&gt;Gemini 3 Ultra, Flux Pro, DALL-E 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video Generation&lt;/td&gt;
&lt;td&gt;Veo 3.1, Sora Turbo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-Speech&lt;/td&gt;
&lt;td&gt;ElevenLabs, MiniMax, OpenAI TTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Music&lt;/td&gt;
&lt;td&gt;ElevenLabs Music&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Search&lt;/td&gt;
&lt;td&gt;Perplexity Sonar Pro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Cloudflare Workers + R2 + D1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  A Real Example: My Video Factory
&lt;/h2&gt;

&lt;p&gt;I'm not theorizing. I built a 7-phase automated video pipeline that chains 6 different AI capabilities in a single script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node video-workflow.js https://youtube.com/watch?v&lt;span class="o"&gt;=&lt;/span&gt;xyz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command → transcript extraction → AI script writing → TTS voiceover → video clip generation → background music → ffmpeg assembly → YouTube upload. Fully automated.&lt;/p&gt;

&lt;p&gt;The key insight: this pipeline calls &lt;strong&gt;5 different AI model types&lt;/strong&gt; (LLM, TTS, video gen, image gen, music gen). Without a unified gateway, that's 5 SDKs, 5 API keys, 5 billing dashboards. With SkillBoss, it's one &lt;code&gt;apiCall()&lt;/code&gt; function with different model names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Same function handles everything&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_BASE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/run`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// TTS&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;voice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minimax/speech-01-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;voice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;male-qn-jingying&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Video&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vertex/veo-3.1-fast-generate-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sceneDesc&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Image&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thumb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vertex/gemini-3-pro-image-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;thumbDesc&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Music&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bgm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;replicate/elevenlabs/music&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;moodDesc&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Matters for the Vibe Coding Era
&lt;/h2&gt;

&lt;p&gt;The narrative around AI development in 2026 is "just prompt it." And for frontend work, that's mostly true. But the backend — especially anything involving multiple AI models — is still a mess of fragmented APIs.&lt;/p&gt;

&lt;p&gt;The developers who ship the most interesting AI-powered apps aren't the ones with the best prompts. They're the ones who solved the infrastructure problem first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three things I stopped doing after switching to a unified gateway:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Comparing pricing across 8 AI providers before starting a project&lt;/li&gt;
&lt;li&gt;Writing adapter code to normalize different API response formats&lt;/li&gt;
&lt;li&gt;Maintaining separate error handling for each provider's rate limits&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Three things I started doing:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Building multi-model pipelines in an afternoon&lt;/li&gt;
&lt;li&gt;Swapping models with a one-line change when a better one launches&lt;/li&gt;
&lt;li&gt;Actually shipping AI apps instead of researching which APIs to use&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install (30 seconds)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash

&lt;span class="c"&gt;# Works with Claude Code, Cursor, Windsurf, or direct API calls&lt;/span&gt;
&lt;span class="c"&gt;# New accounts get $2 free credit — no subscription needed&lt;/span&gt;
&lt;span class="c"&gt;# OpenAI-compatible endpoint: https://api.heybossai.com/v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're vibe coding and keep hitting the "but which API do I use for X?" wall — this is the fix.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the most annoying part of working with multiple AI APIs? I'd love to hear your pain points in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>5 Things I Automated This Week That Used to Take Me Hours</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Thu, 12 Mar 2026 16:53:00 +0000</pubDate>
      <link>https://dev.to/elle001923/5-things-i-automated-this-week-that-used-to-take-me-hours-18g2</link>
      <guid>https://dev.to/elle001923/5-things-i-automated-this-week-that-used-to-take-me-hours-18g2</guid>
      <description>&lt;h1&gt;
  
  
  5 Things I Automated This Week That Used to Take Me Hours
&lt;/h1&gt;

&lt;p&gt;I'm a solo developer. I don't have a marketing team, a video editor, or a content writer. What I do have is an AI agent with access to 100+ models — and this week, it ran my entire content operation while I wrote code.&lt;/p&gt;

&lt;p&gt;Here's what I automated, how long it used to take, and what it takes now.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. YouTube Videos: From URL to Upload in 3 Minutes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; 4-6 hours. Watch source video, write script, record voiceover, generate visuals, edit in Premiere, export, upload, write title/description/tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; One command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node video-workflow.js https://youtube.com/watch?v&lt;span class="o"&gt;=&lt;/span&gt;abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My pipeline extracts the transcript (no video download needed), generates a 10-segment script with hooks and CTAs, creates TTS voiceover, AI video clips, background music, and a thumbnail — then assembles everything with ffmpeg and uploads directly to YouTube.&lt;/p&gt;

&lt;p&gt;The script generation alone uses prompts I spent weeks tuning. Every hook follows a formula: specific number + bold claim + curiosity gap. Every segment is 7-10 seconds for maximum retention.&lt;/p&gt;

&lt;p&gt;I've uploaded 4 videos this way. All 1080p with word-by-word subtitles, Ken Burns effects, and crossfade transitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. SEO Blog Posts That Actually Rank
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; 2-3 hours per article. Keyword research, outline, write, edit, format, publish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; Fully automated pipeline.&lt;/p&gt;

&lt;p&gt;I built &lt;code&gt;seo-content-generator.js&lt;/code&gt; that takes a topic cluster, generates keyword-optimized articles, and &lt;code&gt;seo-content-publisher.js&lt;/code&gt; that formats and publishes them. The articles follow SEO best practices — proper heading hierarchy, internal linking, meta descriptions, the works.&lt;/p&gt;

&lt;p&gt;I generated 10 drafts in one batch. The quality is good enough that I only need a 5-minute review before hitting publish.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Dev.to Articles on Autopilot
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; 1-2 hours writing, plus formatting for Dev.to's markdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; I have a &lt;code&gt;devto-reviewer.js&lt;/code&gt; that checks article quality before publishing, and &lt;code&gt;publish-devto-article.js&lt;/code&gt; that handles the API call. Write the draft (or let AI write it), review, publish — all from the terminal.&lt;/p&gt;

&lt;p&gt;The reviewer scores articles on hook strength, technical depth, readability, and CTA effectiveness. If it scores below 80, it rewrites the weak sections automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Multi-Platform Content Distribution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Manually adapting the same content for LinkedIn, Dev.to, Hacker News, Reddit. Each platform has different formatting, tone, and length requirements. 30-60 minutes per platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; One piece of content, automatically adapted for each platform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt; — Professional tone, shorter, with a hook in the first line&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hacker News&lt;/strong&gt; — Technical, no marketing fluff, Show HN format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reddit&lt;/strong&gt; — Community-friendly, value-first, follows subreddit rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev.to&lt;/strong&gt; — Tutorial-style with code blocks and practical takeaways&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have generators for each: &lt;code&gt;hn-post-generator.js&lt;/code&gt;, platform-specific templates, and even a Reddit growth strategy doc that maps which subreddits to target and what content works in each.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Team Notifications Without the Team
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Manually updating stakeholders. "Hey, I published a new video." "Here's this week's content calendar."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; Lark (Feishu) integration handles everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;lark-notifier.js&lt;/code&gt; — Sends alerts when content is published&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lark-daily-mkt.js&lt;/code&gt; — Pushes daily marketing task summaries&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lark-approval.js&lt;/code&gt; — Routes content through an approval workflow before it goes live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even as a solo dev, having an automated approval flow means I catch mistakes before they're public. The bot sends me a preview, I approve in Lark, and it publishes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack Behind All This
&lt;/h2&gt;

&lt;p&gt;Everything runs through &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;SkillBoss&lt;/a&gt; — a single API gateway that connects to 100+ AI models. One install, one API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what gets called under the hood across these automations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Model Used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Script writing&lt;/td&gt;
&lt;td&gt;Claude 4.5 Sonnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content analysis&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Flash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voiceover&lt;/td&gt;
&lt;td&gt;MiniMax Speech-01-Turbo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video clips&lt;/td&gt;
&lt;td&gt;Veo 3.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thumbnails&lt;/td&gt;
&lt;td&gt;Gemini 3 Pro Image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background music&lt;/td&gt;
&lt;td&gt;ElevenLabs Music&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO optimization&lt;/td&gt;
&lt;td&gt;Claude Haiku 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web search&lt;/td&gt;
&lt;td&gt;Perplexity Sonar Pro&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No model switching. No managing 8 different API keys. The agent picks the right model for each task automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Time saved per week:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Video production: ~20 hours → ~15 minutes (4 videos)&lt;/li&gt;
&lt;li&gt;Blog/SEO content: ~10 hours → ~30 minutes (10 articles)&lt;/li&gt;
&lt;li&gt;Social distribution: ~5 hours → ~10 minutes&lt;/li&gt;
&lt;li&gt;Team updates: ~3 hours → 0 (fully automated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Total: ~38 hours → ~1 hour.&lt;/strong&gt; That's an entire work week I got back.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Automation isn't about replacing creativity — it's about removing the repetitive parts.&lt;/strong&gt; I still decide what topics to cover, what angle to take, what message to push. But I don't manually export video timelines, copy-paste between platforms, or format markdown for the 100th time.&lt;/p&gt;

&lt;p&gt;The biggest unlock wasn't any single AI model. It was having them all accessible through one interface, so building a pipeline that chains 5 different AI capabilities takes minutes instead of days.&lt;/p&gt;

&lt;p&gt;If you're a solo developer doing your own marketing — stop doing it manually. The tools exist. String them together.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the most tedious part of your workflow that you wish you could automate? Drop it in the comments — I might build it next.&lt;/em&gt; 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>productivity</category>
      <category>automation</category>
    </item>
    <item>
      <title>I Was Spending $47/Day on AI API Calls. One Flag Cut It to $4.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Wed, 11 Mar 2026 11:55:56 +0000</pubDate>
      <link>https://dev.to/elle001923/i-was-spending-47day-on-ai-api-calls-one-flag-cut-it-to-4-1706</link>
      <guid>https://dev.to/elle001923/i-was-spending-47day-on-ai-api-calls-one-flag-cut-it-to-4-1706</guid>
      <description>&lt;p&gt;Last month I looked at my API bill and almost spit out my coffee. $1,400. Fourteen hundred dollars — for one month of AI API calls. And the worst part? I did it to myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Here's what happened. I'm building an AI agent that handles content workflows — summarization, image generation, text-to-speech, video, the whole stack. When I wrote the code, I did what every developer does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-4-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;  &lt;span class="c1"&gt;// $3.00/1M tokens&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flux-pro-1.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;       &lt;span class="c1"&gt;// $0.05/image&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tts&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elevenlabs/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;      &lt;span class="c1"&gt;// $0.30/1K chars&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I picked the best model for each task. Hardcoded them. Shipped it. Moved on.&lt;/p&gt;

&lt;p&gt;The thing is — &lt;strong&gt;90% of those calls didn't need the expensive model.&lt;/strong&gt; A simple news summary? Claude Sonnet is overkill. Claude Haiku handles it identically. A basic cover image? You don't need Flux Pro. A cheaper model produces the same result.&lt;/p&gt;

&lt;p&gt;But my agent didn't know that. It just used whatever I hardcoded. Every. Single. Time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The One-Line Fix
&lt;/h2&gt;

&lt;p&gt;I work on &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;SkillBoss&lt;/a&gt; — it's an AI gateway that routes calls across 100+ models. We just shipped something called &lt;strong&gt;Save Mode&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's literally a toggle switch. Turn it on, and the system automatically picks the cheapest model that can handle each task. Chat, image, video, TTS — every API call gets routed to the most cost-effective option.&lt;/p&gt;

&lt;p&gt;You don't pick models. You don't compare pricing pages. You just build.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (This Is Where It Gets Ridiculous)
&lt;/h2&gt;

&lt;p&gt;I ran the same 4-step workflow with Save Mode off vs. on:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task:&lt;/strong&gt; Search AI news → Summarize top 3 → Generate cover image → Convert to audio&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Save Mode OFF (Premium)&lt;/th&gt;
&lt;th&gt;Save Mode ON (Auto-routed)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search + Summarize&lt;/td&gt;
&lt;td&gt;gemini-2.5-pro → $0.038&lt;/td&gt;
&lt;td&gt;gemini-2.5-flash → $0.002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rewrite&lt;/td&gt;
&lt;td&gt;claude-4-5-sonnet → $0.030&lt;/td&gt;
&lt;td&gt;claude-haiku-4 → $0.003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cover Image&lt;/td&gt;
&lt;td&gt;flux-pro-1.1 → $0.020&lt;/td&gt;
&lt;td&gt;gemini-3-pro-image → $0.004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total per run&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.088&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.009&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At 100 runs/day:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save Mode OFF:&lt;/strong&gt; $264/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save Mode ON:&lt;/strong&gt; $27/month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;90% savings. Same task. Same output quality.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The expensive models didn't produce noticeably better results for these routine tasks. I was paying Michelin-star prices for a sandwich.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Actually Works
&lt;/h2&gt;

&lt;p&gt;The routing is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your agent makes an API call (chat, image, video, whatever)&lt;/li&gt;
&lt;li&gt;Save Mode analyzes the task complexity&lt;/li&gt;
&lt;li&gt;It routes to the cheapest model that meets the quality threshold&lt;/li&gt;
&lt;li&gt;If you ever need a specific model, just pass it explicitly — that always takes priority
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install in your terminal&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Toggle Save Mode on in your dashboard, and every call through the gateway gets auto-optimized. Works with Claude Code, OpenClaw, Cursor — any agent environment.&lt;/p&gt;

&lt;p&gt;There's also a REST API if you want programmatic control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /v1/pilot/preferences
{ "preference": "price" }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Doesn't Exist Anywhere Else
&lt;/h2&gt;

&lt;p&gt;I looked. OpenRouter makes you pick models manually. LiteLLM — same thing. Every AI gateway out there expects you to write model IDs in your code.&lt;/p&gt;

&lt;p&gt;SkillBoss is the only one where you flip a switch and the routing happens automatically. Your agent just calls the capability it needs (chat, image, tts), and the system figures out the cheapest way to deliver it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Save Mode is live right now at &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;skillboss.co&lt;/a&gt;. Sign up, flip the toggle, install the CLI, and you're done.&lt;/p&gt;

&lt;p&gt;If you've been burning money on AI APIs without realizing it — you probably have been — give it a shot.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What's the most you've ever overpaid for an AI API call before realizing a cheaper model would've worked?&lt;/strong&gt; I want to hear your horror stories. 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built an AI That Writes My Dev.to Articles and Now I Don't Know How to Feel About It</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Mon, 09 Mar 2026 06:31:05 +0000</pubDate>
      <link>https://dev.to/elle001923/i-built-an-ai-that-writes-my-devto-articles-and-now-i-dont-know-how-to-feel-about-it-29g9</link>
      <guid>https://dev.to/elle001923/i-built-an-ai-that-writes-my-devto-articles-and-now-i-dont-know-how-to-feel-about-it-29g9</guid>
      <description>&lt;p&gt;So I did something kind of weird last week. I built a system where Claude Code automatically generates, reviews, and publishes articles to Dev.to. Including this one. Sort of.&lt;/p&gt;

&lt;p&gt;I mean, I'm obviously editing this right now, so it's not &lt;em&gt;fully&lt;/em&gt; automated. But the original draft? That was Claude. The code review? Also Claude. The decision about whether it was good enough to publish? Yeah, you see where this is going.&lt;/p&gt;

&lt;p&gt;The whole thing started because I kept procrastinating on writing. I'd have these ideas and open a blank file and just... stare at it. Classic developer problem, right? So I thought, what if I could just tell an AI agent what I wanted to write about and it would handle the boring parts?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture (or: How Deep Does This Rabbit Hole Go?)
&lt;/h2&gt;

&lt;p&gt;The system has three agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You write technical blog posts. Be honest about failures.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchWeb&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="na"&gt;reviewer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Review articles for authenticity. Flag AI slop.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;analyzeText&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="na"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Publish to Dev.to only if quality threshold met&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;publishToDevTo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The writer agent takes a topic and generates a draft. Then the reviewer agent reads it and decides if it sounds like an actual human wrote it or if it's that generic AI voice we all hate. If it passes, the publisher agent posts it.&lt;/p&gt;

&lt;p&gt;Here's where it gets uncomfortable: the reviewer rejected the first seven drafts. I was honestly surprised. I'd look at them and think "this seems fine?" but the reviewer would flag things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"This paragraph uses three adjectives before every noun"&lt;/li&gt;
&lt;li&gt;"No actual code examples, just pseudo-code" &lt;/li&gt;
&lt;li&gt;"Ends with 'embarking on a journey' unironically"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which... fair.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SkillBoss Problem
&lt;/h2&gt;

&lt;p&gt;I hit a weird issue around day three. The agents kept losing context about what we were building. The writer would generate something, the reviewer would give feedback, but then the writer would forget that feedback in the next iteration.&lt;/p&gt;

&lt;p&gt;I needed some way to maintain state across agent calls. I tried a bunch of approaches (Redis, just writing to files, keeping everything in memory) before I remembered SkillBoss had that skill tree concept where agents can save and load context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SkillTree&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;skillboss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentTree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SkillTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article-workflow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Writer saves its output&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contentTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveProgress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;draft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;iteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reviewerFeedback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;previousFeedback&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Reviewer loads it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reviewerFeedback&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contentTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadProgress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;draft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agents actually learn from previous iterations instead of just... forgetting everything every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Uncomfortable Part
&lt;/h2&gt;

&lt;p&gt;So now I have this system that can generate articles. And they're not bad? Like, the reviewer is pretty strict. It rejects anything that sounds too polished or uses those weird AI phrases.&lt;/p&gt;

&lt;p&gt;But I keep thinking: am I just teaching an AI to fake my voice? The reviewer looks for things like "uneven paragraph lengths" and "admitting uncertainty" and "specific technical details." It's essentially a rubric for sounding human.&lt;/p&gt;

&lt;p&gt;Which is what I'm doing right now, as a human, right? Following patterns I've learned from reading other Dev.to posts?&lt;/p&gt;

&lt;p&gt;I don't have a clean conclusion here. The system works. It saves me time. The articles it generates are helpful to people (based on the comments on the last one it published). But there's something uncanny about reading something that sounds like you but you didn't write.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is the actual check the reviewer does&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;soundsHuman&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no first person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sr"&gt;.&lt;/span&gt;&lt;span class="se"&gt;{0,50}\n\n&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;too many short paragraphs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no code blocks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the function that decided this article was human enough to publish.&lt;/p&gt;

&lt;p&gt;Was it right?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Replaced 12 AI Subscriptions with One CLI Command</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Mon, 09 Mar 2026 03:51:41 +0000</pubDate>
      <link>https://dev.to/elle001923/i-replaced-12-ai-subscriptions-with-one-cli-command-4j6m</link>
      <guid>https://dev.to/elle001923/i-replaced-12-ai-subscriptions-with-one-cli-command-4j6m</guid>
      <description>&lt;p&gt;Last month, I was juggling &lt;strong&gt;12 different AI subscriptions&lt;/strong&gt;. OpenAI for GPT. Anthropic for Claude. ElevenLabs for voice. Runway for video. Replicate for music. Google for Gemini. The list kept growing.&lt;/p&gt;

&lt;p&gt;My credit card statement looked like a SaaS graveyard. And every time I wanted to build something that combined multiple AI capabilities? I'd spend more time wrangling API keys than writing actual code.&lt;/p&gt;

&lt;p&gt;Then I built something that changed everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;The AI ecosystem is fragmented by design. Every provider wants you locked into their platform. Want to generate an image with Flux, turn it into a video with Veo, add voiceover with ElevenLabs, and deploy the result to the web? That's &lt;strong&gt;4 API keys, 4 billing dashboards, 4 different SDKs, and 4 different authentication flows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a solo developer, this is death by a thousand paper cuts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built an automated YouTube video factory. One command. Zero manual editing. Here's what it does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node video-workflow.js https://youtube.com/watch?v&lt;span class="o"&gt;=&lt;/span&gt;xyz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single command triggers a &lt;strong&gt;7-phase pipeline&lt;/strong&gt; that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extracts video metadata and transcripts (no download needed)&lt;/li&gt;
&lt;li&gt;Analyzes content using Gemini Vision&lt;/li&gt;
&lt;li&gt;Generates a world-class script with hook, insights, and CTA&lt;/li&gt;
&lt;li&gt;Creates TTS voiceover, AI video clips, thumbnail, and background music&lt;/li&gt;
&lt;li&gt;Assembles everything with cinematic transitions, word-by-word subtitles, and Ken Burns effects&lt;/li&gt;
&lt;li&gt;Uploads to YouTube with optimized title, description, and tags&lt;/li&gt;
&lt;li&gt;Self-evaluates the output and generates improvements for the next run&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; 4-6 hours per video, manually switching between 8 tools.&lt;br&gt;
&lt;strong&gt;After:&lt;/strong&gt; 3 minutes. Fully automated. Consistently scoring 85+ on my quality rubric.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Secret Sauce: One Gateway, 100+ Models
&lt;/h2&gt;

&lt;p&gt;The magic isn't in any single AI model — it's in the orchestration layer. I use &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;SkillBoss&lt;/a&gt; as a unified API gateway that gives me access to &lt;strong&gt;100+ AI models&lt;/strong&gt; through a single endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One install. One API key. One billing dashboard. Here's what I get:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Models Available&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chat/Reasoning&lt;/td&gt;
&lt;td&gt;Claude 4.5, GPT-5, Gemini 3, DeepSeek R1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Generation&lt;/td&gt;
&lt;td&gt;Gemini 3 Ultra, Flux Pro, DALL-E 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video Generation&lt;/td&gt;
&lt;td&gt;Veo 3.1, Sora Turbo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-Speech&lt;/td&gt;
&lt;td&gt;ElevenLabs, MiniMax, OpenAI TTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Music Generation&lt;/td&gt;
&lt;td&gt;ElevenLabs Music via Replicate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Search&lt;/td&gt;
&lt;td&gt;Perplexity Sonar Pro (with citations)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Scraping&lt;/td&gt;
&lt;td&gt;Firecrawl, ScrapingDog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Cloudflare Workers + R2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The best part? &lt;strong&gt;Pay-as-you-go pricing&lt;/strong&gt;. No monthly subscriptions. I went from ~$180/month in AI subscriptions to spending only what I actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive: The 7 Phases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Intelligence Gathering (No Video Download)
&lt;/h3&gt;

&lt;p&gt;YouTube's SABR protocol blocks most video downloaders. Instead of fighting it, I extract only what I need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Metadata only — no video download needed&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`yt-dlp --dump-json --skip-download "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`python3 -m youtube_transcript_api "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;videoId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives me the title, description, duration, view count, and full transcript — everything needed for content analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: World-Class Script Generation
&lt;/h3&gt;

&lt;p&gt;This is where the magic happens. I don't just "summarize" the source video. I use Claude to generate scripts that follow &lt;strong&gt;YouTube retention science&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hook formula:&lt;/strong&gt; Specific number + bold claim + curiosity gap&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8-10 segments&lt;/strong&gt;, each 7-10 seconds (scene changes every ~8s = high retention signal)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTA:&lt;/strong&gt; Specific benefit, never generic "like and subscribe"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The prompt engineering alone took weeks to perfect. Every script gets structured as JSON with narration text, visual descriptions, and timing metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Parallel Asset Generation
&lt;/h3&gt;

&lt;p&gt;This is where having a unified API gateway pays off. I fire off &lt;strong&gt;multiple AI calls simultaneously&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ttsResults&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bgmResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thumbnailResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;videoClips&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;generateTTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;        &lt;span class="c1"&gt;// ElevenLabs or MiniMax&lt;/span&gt;
    &lt;span class="nf"&gt;generateBGM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bgmPrompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;       &lt;span class="c1"&gt;// Replicate&lt;/span&gt;
    &lt;span class="nf"&gt;generateThumbnail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thumbPrompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Gemini 3 Ultra Image&lt;/span&gt;
    &lt;span class="nf"&gt;generateVideoClips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// Veo 3.1 with fallback&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No juggling API keys. No switching SDKs. Same &lt;code&gt;apiCall()&lt;/code&gt; function for everything — just different model names.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 5: FFmpeg Wizardry
&lt;/h3&gt;

&lt;p&gt;This phase assembles everything into a polished video. Some hard-won lessons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word-by-word subtitles&lt;/strong&gt; using ASS format with karaoke tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{\kf80}Every {\kf60}word {\kf70}highlights {\kf90}individually
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ken Burns effect&lt;/strong&gt; on static images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zoompan=z='min(zoom+0.0015,1.5)':d=180:s=1920x1080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BGM mixing&lt;/strong&gt; — keep it simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DON'T use loudnorm + sidechaincompress (hangs indefinitely)
// DO use simple volume control
amix=inputs=2:duration=first [mixed]; [mixed] volume=0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one cost me 2 hours of debugging. The &lt;code&gt;sidechaincompress&lt;/code&gt; filter in ffmpeg creates a deadlock with &lt;code&gt;loudnorm&lt;/code&gt; in certain filter graph configurations. A simple &lt;code&gt;volume=0.12&lt;/code&gt; for background music works perfectly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 7: Self-Evaluation Loop
&lt;/h3&gt;

&lt;p&gt;After upload, the pipeline evaluates itself across 5 dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook strength (does it grab attention in 3 seconds?)&lt;/li&gt;
&lt;li&gt;Content value density (insight per second)&lt;/li&gt;
&lt;li&gt;SEO optimization (title, description, tags)&lt;/li&gt;
&lt;li&gt;Audio-visual quality (transitions, subtitle timing, BGM balance)&lt;/li&gt;
&lt;li&gt;Conversion potential (CTA effectiveness)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Score below 85? It generates specific improvements and saves them to &lt;code&gt;next_run_improvements.json&lt;/code&gt; for the next run. The system literally gets better every time it runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Results
&lt;/h2&gt;

&lt;p&gt;Here's a video this pipeline produced — fully automated, zero manual editing:&lt;/p&gt;

&lt;p&gt;🎬 &lt;a href="https://www.youtube.com/watch?v=87gtJia6sR0" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1080p, Veo 3.1 video clips, professional transitions, word-by-word subtitles, background music, and auto-generated thumbnail.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Model fallbacks are essential.&lt;/strong&gt; Every AI model has rate limits and outages. My pipeline has automatic fallback chains (Veo 3.1 → Sora Turbo → image-to-video). It never fails completely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Binary data handling matters.&lt;/strong&gt; Early on, I was concatenating audio buffers as strings (&lt;code&gt;raw += chunk&lt;/code&gt;). The audio came out corrupted. Switching to &lt;code&gt;Buffer.concat(chunks)&lt;/code&gt; fixed it instantly. Seems obvious in hindsight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Don't over-engineer audio mixing.&lt;/strong&gt; FFmpeg's &lt;code&gt;sidechaincompress&lt;/code&gt; and &lt;code&gt;loudnorm&lt;/code&gt; are powerful but can deadlock in complex filter graphs. Sometimes the simple solution (&lt;code&gt;volume=0.12&lt;/code&gt;) is the correct one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The unified API gateway was the breakthrough.&lt;/strong&gt; Not because any individual model was special, but because the orchestration became trivial. When adding a new capability means changing one model name instead of integrating a new SDK, you build things you never would have attempted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;If you want to try the multi-model approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install SkillBoss&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash

&lt;span class="c"&gt;# Use with Claude Code, Cursor, or any AI coding assistant&lt;/span&gt;
&lt;span class="c"&gt;# Or use the OpenAI-compatible endpoint directly:&lt;/span&gt;
&lt;span class="c"&gt;# https://api.skillboss.co/v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New accounts get $2 in free credits. No subscription needed.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the most complex AI pipeline you've built? I'd love to hear about multi-model workflows in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Tried to Ship a SaaS with OpenClaw. It Couldn't. Here's What Fixed It.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Sun, 08 Mar 2026 15:05:20 +0000</pubDate>
      <link>https://dev.to/elle001923/i-tried-to-ship-a-saas-with-openclaw-it-couldnt-heres-what-fixed-it-3i7e</link>
      <guid>https://dev.to/elle001923/i-tried-to-ship-a-saas-with-openclaw-it-couldnt-heres-what-fixed-it-3i7e</guid>
      <description>&lt;h1&gt;
  
  
  I Tried to Ship a SaaS with OpenClaw. It Couldn't. Here's What Fixed It.
&lt;/h1&gt;

&lt;p&gt;I've been obsessed with OpenClaw for the past few months.&lt;/p&gt;

&lt;p&gt;If you haven't tried it yet — it's an AI agent framework that lets you give your AI a goal, and it figures out how to get there. Task boards, memory, agent panels, multi-step workflows. It's genuinely impressive engineering.&lt;/p&gt;

&lt;p&gt;But I kept running into the same wall.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;I built a project management tool with OpenClaw. The agent wrote clean code, handled edge cases, even refactored itself when I asked. I was genuinely excited.&lt;/p&gt;

&lt;p&gt;Then I tried to ship it.&lt;/p&gt;

&lt;p&gt;No deployment. No payments. No auth. No email notifications. Just a beautiful app sitting on &lt;code&gt;localhost:3000&lt;/code&gt; that nobody could use.&lt;/p&gt;

&lt;p&gt;OpenClaw is incredible at building. But it has zero infrastructure for shipping.&lt;/p&gt;

&lt;p&gt;And I'm not talking about writing more code — I mean the actual plumbing every real product needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A live URL that doesn't die when I close my laptop&lt;/li&gt;
&lt;li&gt;Stripe so users can actually pay me&lt;/li&gt;
&lt;li&gt;Auth so users can log in&lt;/li&gt;
&lt;li&gt;Email so I can notify users when something happens&lt;/li&gt;
&lt;li&gt;A database that isn't just local state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I spent two weeks gluing these things together manually. It was painful, slow, and completely defeated the point of having an AI agent in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Found
&lt;/h2&gt;

&lt;p&gt;A friend mentioned SkillBoss. I was skeptical — another "AI infrastructure" tool sounded like marketing fluff.&lt;/p&gt;

&lt;p&gt;One command to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skillboss.co/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then something clicked.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Changes
&lt;/h2&gt;

&lt;p&gt;SkillBoss sits between your AI agent and everything else. It gives your agent a single API to access:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100+ AI models&lt;/strong&gt; — not just Claude. Reasoning models for complex tasks, fast cheap models for simple ones, vision models that read screenshots, search models that browse the web in real time. Your agent picks the right one automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy in 90 seconds&lt;/strong&gt; — run one command and your app is live on a real URL, hosted on Cloudflare's global edge network. I timed it. It's actually 90 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe payments&lt;/strong&gt; — your agent can set up subscription plans, handle checkouts, process refunds. No manual Stripe dashboard configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth&lt;/strong&gt; — user accounts, OAuth, two-factor auth, permissions. All through the same API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactional email and SMS&lt;/strong&gt; — your agent can send emails and texts without you setting up an SMTP server or Twilio account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Media generation&lt;/strong&gt; — images, videos, voice cloning, background music. One API call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web intelligence&lt;/strong&gt; — search the web in real time, scrape any site, parse PDFs, extract data from documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part That Surprised Me Most
&lt;/h2&gt;

&lt;p&gt;I expected to spend a day reading docs. Instead, I just told my OpenClaw agent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Deploy this project and set up Stripe for a $29/month subscription"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It figured out the rest. The agent called SkillBoss APIs for deployment, set up the payment flow, configured the success/cancel URLs, and sent me a live link.&lt;/p&gt;

&lt;p&gt;Start to finish: under 10 minutes.&lt;/p&gt;

&lt;p&gt;The project management tool I'd been stuck on for two weeks was live and taking payments before lunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mix and Match Models
&lt;/h2&gt;

&lt;p&gt;This is the feature I didn't expect to care about but now can't live without.&lt;/p&gt;

&lt;p&gt;Every OpenClaw workflow makes multiple AI calls — searching, summarizing, reasoning, generating. Before SkillBoss, all of those calls went to whichever model I had configured. Expensive models doing simple tasks. Cheap models struggling with complex ones.&lt;/p&gt;

&lt;p&gt;With SkillBoss, the agent automatically routes each call to the right model type. A fast, cheap model handles summaries. A vision model reads screenshots. A reasoning model handles the hard decisions. A search model handles web queries.&lt;/p&gt;

&lt;p&gt;Same workflow. Better results. Lower cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Use It With
&lt;/h2&gt;

&lt;p&gt;SkillBoss works with all the major AI coding environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenClaw&lt;/li&gt;
&lt;li&gt;Claude Code&lt;/li&gt;
&lt;li&gt;Cursor&lt;/li&gt;
&lt;li&gt;Code X&lt;/li&gt;
&lt;li&gt;Windsurf&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using any of these, the integration is zero friction. Your existing workflows just gain new capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Honest Part
&lt;/h2&gt;

&lt;p&gt;I still use OpenClaw for everything I used to use it for. It's genuinely the best AI agent framework I've tried.&lt;/p&gt;

&lt;p&gt;But I think of it differently now. OpenClaw is where I build. SkillBoss is how I ship.&lt;/p&gt;

&lt;p&gt;If you've been building things with OpenClaw or Claude Code that never quite make it to production — this is probably the missing piece.&lt;/p&gt;

&lt;p&gt;Try it free: &lt;a href="https://skillboss.co" rel="noopener noreferrer"&gt;skillboss.co&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you shipped something with OpenClaw + SkillBoss? Drop it in the comments — I'm collecting real examples.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>claudecode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I automated my YouTube workflow with Node.js. The hard part wasn't the code.</title>
      <dc:creator>Elle</dc:creator>
      <pubDate>Tue, 03 Mar 2026 12:23:13 +0000</pubDate>
      <link>https://dev.to/elle001923/i-automated-my-youtube-workflow-with-nodejs-the-hard-part-wasnt-the-code-3ef</link>
      <guid>https://dev.to/elle001923/i-automated-my-youtube-workflow-with-nodejs-the-hard-part-wasnt-the-code-3ef</guid>
      <description>&lt;p&gt;I wanted to stop spending weekends editing videos, so I built a pipeline that takes a YouTube URL and outputs a fully produced video ready to upload — script, voiceover, AI clips, subtitles, thumbnail, the whole thing. About 200 lines of Node.js orchestrating a bunch of AI APIs.&lt;/p&gt;

&lt;p&gt;It mostly works. But the part that broke the most often wasn't ffmpeg or the subtitle timing or the YouTube upload auth. It was figuring out what to actually make.&lt;/p&gt;

&lt;p&gt;The general shape: fetch transcript → Claude analyzes and writes a new script → Minimax TTS for voiceover → Veo generates video clips → ffmpeg assembles everything → uploads to YouTube.&lt;/p&gt;

&lt;p&gt;The messiest part was handling five different AI APIs in one script. Each has its own SDK, its own auth pattern, its own response format. I kept having to look up whether the response was at data.choices[0].message.content or data.content[0].text or somewhere else entirely.&lt;/p&gt;

&lt;p&gt;I ended up switching to SkillBoss, which is a gateway that puts all of them behind one endpoint. The call shape is the same regardless of which model you're hitting&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const run = async (model, inputs) =&amp;gt; {
  const res = await fetch('https://api.heybossai.com/v1/run', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.SKILLBOSS_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ model, inputs })
  })
  return res.json()
}

// script generation
const script = await run('bedrock/claude-4-5-sonnet', { messages: [...] })

// video clips
const clip = await run('vertex/veo-3.1-fast-generate-preview', { prompt, duration: 6 })

// voiceover
const audio = await run('minimax/speech-01-turbo', { text, voice_setting: { voice_id: 'male-qn-jingying' } })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One import, one auth token, one response parsing pattern. Not revolutionary, but when you're switching between five models in the same file it actually matters.&lt;/p&gt;

&lt;p&gt;Once the pipeline was running, I realized I had no good answer for what content to put into it.&lt;/p&gt;

&lt;p&gt;I'd been watching OpenClaw threads for a while — people sharing use cases, builds, workflows. One thread from a few weeks ago had 200+ upvotes: someone building a multi-agent research system that automatically synthesizes papers, generates summaries, and routes findings to different Notion databases by topic. Impressive setup. I checked their profile two weeks later — no follow-up post, the GitHub repo had two commits both on the same day.&lt;/p&gt;

&lt;p&gt;Meanwhile the projects that do ship tend to look different. Smaller. More personal. An eye drop reminder that reads a prescription label and sends Telegram alerts. A morning briefing that pulls from three RSS feeds. A script that auto-categorizes a folder of receipts. Nobody posts these as big announcements. They just... work, because done means "it works for me" and there's no external bar.&lt;/p&gt;

&lt;p&gt;I think this is the actual trap with agentic tools: they make starting easy, which makes it tempting to start ambitious things. But the gap between "got it working in a demo" and "I've been using this for two months" is mostly not a technical gap.&lt;/p&gt;

&lt;p&gt;For my own use, I ended up narrowing the scope significantly from what I originally planned. The pipeline doesn't try to research topics or pick what to make — I still do that. It doesn't handle edge cases I haven't hit yet. It doesn't have a UI.&lt;/p&gt;

&lt;p&gt;It does one thing: given a YouTube URL with interesting content, it makes a shorter, re-narrated version with decent production value. That's it. I've made 11 videos with it so far, uploaded 4, scrapped the rest because the source material wasn't interesting enough — which is a content problem, not a pipeline problem. It keeps running.&lt;/p&gt;

&lt;p&gt;The interesting remaining question for me is whether the "small scope, personal use" pattern holds as these tools get better at handling the hard 40% — or whether ambition will always outpace the capability ceiling. Based on what I've seen in OpenClaw threads, I lean toward the former being a feature of the people building, not just the tools.&lt;/p&gt;

&lt;p&gt;If you've shipped something agentic that you're still using six months later, I'm curious what the scope looked like when you first had the idea vs. what you actually built.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>scrips</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
