<?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: brian austin</title>
    <description>The latest articles on DEV Community by brian austin (@subprime2010).</description>
    <link>https://dev.to/subprime2010</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%2F3759118%2Ff305d263-a62f-4ba8-918f-18236fc5a13e.png</url>
      <title>DEV Community: brian austin</title>
      <link>https://dev.to/subprime2010</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/subprime2010"/>
    <language>en</language>
    <item>
      <title>Building a Telegram bot with Claude API for under $2/month (complete tutorial)</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 13:17:28 +0000</pubDate>
      <link>https://dev.to/subprime2010/building-a-telegram-bot-with-claude-api-for-under-2month-complete-tutorial-584a</link>
      <guid>https://dev.to/subprime2010/building-a-telegram-bot-with-claude-api-for-under-2month-complete-tutorial-584a</guid>
      <description>&lt;h1&gt;
  
  
  Building a Telegram bot with Claude API for under $2/month
&lt;/h1&gt;

&lt;p&gt;I've been running a Telegram bot powered by Claude for several months. Last month it cost me less than $2. Here's the complete setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Telegram + Claude?
&lt;/h2&gt;

&lt;p&gt;Telegram bots are everywhere — customer support, personal assistants, group moderation, notification systems. The problem: most tutorials show you how to hook up OpenAI at $20/month or build your own Anthropic API key at $15+ per million tokens.&lt;/p&gt;

&lt;p&gt;There's a cheaper path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; + &lt;code&gt;node-telegram-bot-api&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SimplyLouie API&lt;/strong&gt; ($2/month, Claude-powered)&lt;/li&gt;
&lt;li&gt;A free VPS or Fly.io hobby tier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup in 10 minutes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create your Telegram bot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Talk to @BotFather on Telegram&lt;/span&gt;
&lt;span class="c"&gt;# Send: /newbot&lt;/span&gt;
&lt;span class="c"&gt;# Follow the prompts, get your token&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TELEGRAM_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-bot-token-here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-claude-bot &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-claude-bot
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;node-telegram-bot-api axios dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. The complete bot (&amp;lt; 80 lines)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&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;TelegramBot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-telegram-bot-api&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;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&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;bot&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;TelegramBot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELEGRAM_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;polling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Conversation history per user&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conversations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&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;askClaude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&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;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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="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;message&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Keep last 10 messages to control token usage&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;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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://simplylouie.com/api/chat&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;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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-haiku-20241022&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;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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOUIE_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="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="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;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="mi"&gt;0&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;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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="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;assistant&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;reply&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;reply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;bot&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;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&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;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msg&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;id&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="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="nx"&gt;msg&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;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Show typing indicator&lt;/span&gt;
  &lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendChatAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;typing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&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;reply&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;askClaude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;parse_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Markdown&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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;Claude error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sorry, something went wrong. Try again.&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="nx"&gt;bot&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;polling_error&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;err&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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;Polling error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bot running...&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;h3&gt;
  
  
  4. Environment file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env&lt;/span&gt;
&lt;span class="nv"&gt;TELEGRAM_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-telegram-token
&lt;span class="nv"&gt;LOUIE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-api-key-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get your API key at &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;simplylouie.com/developers&lt;/a&gt; — $2/month includes Claude access.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Deploy to Fly.io (free tier)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install flyctl&lt;/span&gt;
curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://fly.io/install.sh | sh

&lt;span class="c"&gt;# Deploy&lt;/span&gt;
fly launch
fly secrets &lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;TELEGRAM_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxx &lt;span class="nv"&gt;LOUIE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxx
fly deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your bot is now running 24/7 for free (Fly.io hobby) + $2/month for the Claude API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world use cases I've built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Personal assistant bot&lt;/strong&gt; — answers questions, drafts emails, summarizes articles I paste&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer FAQ bot&lt;/strong&gt; — trained on a system prompt with product info, handles 80% of support questions automatically&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code review bot&lt;/strong&gt; — add it to a dev group, paste code snippets, get instant review&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language learning bot&lt;/strong&gt; — practice conversations in Spanish/French with corrections&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlling costs
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;slice(-10)&lt;/code&gt; in the code above is important — it limits conversation history to 10 messages, keeping token usage predictable. For a personal bot with moderate usage, you'll comfortably stay within the $2/month plan.&lt;/p&gt;

&lt;p&gt;If you're building for multiple users (like a customer support bot), the usage scales up. Check the &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;developers page&lt;/a&gt; for API tier pricing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending the bot
&lt;/h2&gt;

&lt;p&gt;Add a system prompt for personality:&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;askClaude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&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;systemPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are a helpful assistant for a software development team. Be concise, technical, and use code examples when helpful.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// ... rest of the function&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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://simplylouie.com/api/chat&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;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&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="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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-haiku-20241022&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&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;Add &lt;code&gt;/reset&lt;/code&gt; command to clear conversation history:&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="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onText&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;reset/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&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;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msg&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;id&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="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Conversation cleared ✓&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The full code on GitHub
&lt;/h2&gt;

&lt;p&gt;I've open-sourced the complete bot template: the code above is production-ready as-is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this costs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Telegram Bot API: &lt;strong&gt;free&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fly.io hobby tier: &lt;strong&gt;free&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;SimplyLouie Claude API: &lt;strong&gt;$2/month&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: $2/month for a production-grade AI Telegram bot.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;SimplyLouie is a $2/month Claude API wrapper with no rate limits and no complex billing. Get your API key at &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;simplylouie.com/developers&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>claude</category>
      <category>api</category>
      <category>node</category>
    </item>
    <item>
      <title>How I automate code reviews with Claude API for $2/month (GitHub Actions walkthrough)</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 12:17:59 +0000</pubDate>
      <link>https://dev.to/subprime2010/how-i-automate-code-reviews-with-claude-api-for-2month-github-actions-walkthrough-jc2</link>
      <guid>https://dev.to/subprime2010/how-i-automate-code-reviews-with-claude-api-for-2month-github-actions-walkthrough-jc2</guid>
      <description>&lt;h1&gt;
  
  
  How I automate code reviews with Claude API for $2/month (GitHub Actions walkthrough)
&lt;/h1&gt;

&lt;p&gt;Code reviews take time. Good ones take even more time. I've been experimenting with automating the boring parts — style issues, obvious bugs, missing error handling — so humans can focus on architecture and logic.&lt;/p&gt;

&lt;p&gt;Here's the full GitHub Actions setup I'm running, with real examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with manual code review
&lt;/h2&gt;

&lt;p&gt;On a solo project or small team, code review is either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You reviewing your own code (which misses the obvious stuff)&lt;/li&gt;
&lt;li&gt;Waiting for a teammate who's busy&lt;/li&gt;
&lt;li&gt;Not happening at all&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI review isn't a replacement for human judgment, but it catches the mechanical stuff instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup: GitHub Actions + Claude API
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;SimplyLouie's developer API&lt;/a&gt; — it's $2/month flat, no per-token billing to worry about.&lt;/p&gt;

&lt;p&gt;Here's the workflow file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/ai-review.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Code Review&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get PR diff&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;diff&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git diff origin/${{ github.base_ref }}...HEAD &amp;gt; /tmp/pr.diff&lt;/span&gt;
          &lt;span class="s"&gt;echo "diff_size=$(wc -l &amp;lt; /tmp/pr.diff)" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Review&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.diff.outputs.diff_size &amp;lt; &lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;DIFF=$(cat /tmp/pr.diff)&lt;/span&gt;
          &lt;span class="s"&gt;RESPONSE=$(curl -s -X POST https://simplylouie.com/api/chat \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Authorization: Bearer ${{ secrets.LOUIE_API_KEY }}" \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Content-Type: application/json" \&lt;/span&gt;
            &lt;span class="s"&gt;-d "{&lt;/span&gt;
              &lt;span class="s"&gt;\"message\": \"Review this code diff. Flag: (1) potential bugs, (2) missing error handling, (3) security issues. Be concise. Format as markdown bullet points.\\n\\n$DIFF\"&lt;/span&gt;
            &lt;span class="s"&gt;}")&lt;/span&gt;
          &lt;span class="s"&gt;echo "$RESPONSE" &amp;gt; /tmp/review.md&lt;/span&gt;
          &lt;span class="s"&gt;cat /tmp/review.md&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Post review comment&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/github-script@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;const fs = require('fs');&lt;/span&gt;
            &lt;span class="s"&gt;const review = fs.readFileSync('/tmp/review.md', 'utf8');&lt;/span&gt;
            &lt;span class="s"&gt;github.rest.issues.createComment({&lt;/span&gt;
              &lt;span class="s"&gt;issue_number: context.issue.number,&lt;/span&gt;
              &lt;span class="s"&gt;owner: context.repo.owner,&lt;/span&gt;
              &lt;span class="s"&gt;repo: context.repo.repo,&lt;/span&gt;
              &lt;span class="s"&gt;body: `## 🤖 AI Code Review\n\n${review}\n\n*Automated review by SimplyLouie API*`&lt;/span&gt;
            &lt;span class="s"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real example output
&lt;/h2&gt;

&lt;p&gt;Here's what it flagged on a recent PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## 🤖 AI Code Review

**Potential bugs:**
- Line 47: `user.id` accessed without null check — will throw if user is undefined
- Line 89: Promise not awaited in async function — silent failure possible

**Missing error handling:**
- Line 102: Database query has no try/catch — unhandled rejection on connection failure

**Security:**
- Line 156: User input interpolated directly into SQL string — parameterize this query

*Automated review by SimplyLouie API*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That SQL injection flag alone saved me from a production issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API call explained
&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;# Simple test&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "message": "Review this code for bugs and security issues:\n\nfunction getUser(id) { return db.query(\"SELECT * FROM users WHERE id=\" + id); }"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security issue: SQL injection vulnerability. The `id` parameter is concatenated directly into the query string. Use parameterized queries instead:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;```

sql&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM users WHERE id = ?&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;

```&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Pass `id` as a bound parameter to prevent injection attacks."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;SimplyLouie API: $2/month flat&lt;/li&gt;
&lt;li&gt;GitHub Actions: free for public repos, 2000 minutes/month free for private&lt;/li&gt;
&lt;li&gt;Total for a 10-person team doing 50 PRs/month: &lt;strong&gt;$2&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anthropic Claude API direct: ~$0.003/review × 50 PRs = $0.15/month (but you need account setup, billing, rate limit management)&lt;/li&gt;
&lt;li&gt;GitHub Copilot for Business: $19/user/month = $190/month&lt;/li&gt;
&lt;li&gt;Manual review time: 30 min × 50 PRs × $50/hr = $1,250/month of human time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Customizing the review prompt
&lt;/h2&gt;

&lt;p&gt;Different projects need different review focus:&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;# For a security-sensitive API:&lt;/span&gt;
&lt;span class="s2"&gt;"Review for: SQL injection, XSS, SSRF, authentication bypass, secrets in code"&lt;/span&gt;

&lt;span class="c"&gt;# For a React frontend:&lt;/span&gt;
&lt;span class="s2"&gt;"Review for: missing key props, useEffect dependency arrays, unnecessary re-renders, accessibility"&lt;/span&gt;

&lt;span class="c"&gt;# For a Node.js backend:&lt;/span&gt;
&lt;span class="s2"&gt;"Review for: unhandled promise rejections, missing input validation, N+1 queries, memory leaks"&lt;/span&gt;

&lt;span class="c"&gt;# For a data pipeline:&lt;/span&gt;
&lt;span class="s2"&gt;"Review for: silent data loss, missing type validation, performance with large datasets"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;This works best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PRs under 500 lines (larger diffs lose context)&lt;/li&gt;
&lt;li&gt;Catching mechanical issues (not architectural decisions)&lt;/li&gt;
&lt;li&gt;Projects with consistent coding patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not a replacement for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security audits&lt;/li&gt;
&lt;li&gt;Performance profiling&lt;/li&gt;
&lt;li&gt;Architecture review&lt;/li&gt;
&lt;li&gt;Business logic validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt; — $2/month, 7-day free trial&lt;/li&gt;
&lt;li&gt;Get your API key from the dashboard&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;LOUIE_API_KEY&lt;/code&gt; to your GitHub repo secrets&lt;/li&gt;
&lt;li&gt;Copy the workflow file above&lt;/li&gt;
&lt;li&gt;Open a PR and watch the review appear&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The whole setup takes about 10 minutes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions about the GitHub Actions setup? Drop them in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>ai</category>
      <category>github</category>
    </item>
    <item>
      <title>How developers in Africa are building with AI on $2/month (and what Silicon Valley gets wrong)</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 09:47:31 +0000</pubDate>
      <link>https://dev.to/subprime2010/how-developers-in-africa-are-building-with-ai-on-2month-and-what-silicon-valley-gets-wrong-590d</link>
      <guid>https://dev.to/subprime2010/how-developers-in-africa-are-building-with-ai-on-2month-and-what-silicon-valley-gets-wrong-590d</guid>
      <description>&lt;h1&gt;
  
  
  How developers in Africa are building with AI on $2/month (and what Silicon Valley gets wrong)
&lt;/h1&gt;

&lt;p&gt;I was on a Zoom call last month with a developer in Lagos. He was building a client project — a WhatsApp chatbot for a local logistics company. Smart architecture, clean code, solid product thinking.&lt;/p&gt;

&lt;p&gt;He mentioned he couldn't use ChatGPT for the project. Not because of technical limitations. Because $20/month is ₦32,000 — roughly 3 days of after-rent income for a mid-level developer in Lagos.&lt;/p&gt;

&lt;p&gt;"I just use the free tier and work around the rate limits," he said.&lt;/p&gt;

&lt;p&gt;That "working around" is costing him hours every week.&lt;/p&gt;




&lt;h2&gt;
  
  
  The math Silicon Valley ignores
&lt;/h2&gt;

&lt;p&gt;When a San Francisco engineer complains that ChatGPT costs "only $20/month," they're doing math in USD purchasing power. But the world doesn't run on San Francisco purchasing power.&lt;/p&gt;

&lt;p&gt;Here's what $20/month actually costs across the developer world:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Monthly AI cost&lt;/th&gt;
&lt;th&gt;As % of avg dev salary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;USA&lt;/td&gt;
&lt;td&gt;$20&lt;/td&gt;
&lt;td&gt;~0.05%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UK&lt;/td&gt;
&lt;td&gt;£16&lt;/td&gt;
&lt;td&gt;~0.07%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nigeria&lt;/td&gt;
&lt;td&gt;₦32,000&lt;/td&gt;
&lt;td&gt;~8-12%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kenya&lt;/td&gt;
&lt;td&gt;KSh2,600&lt;/td&gt;
&lt;td&gt;~5-8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ghana&lt;/td&gt;
&lt;td&gt;GH₵250&lt;/td&gt;
&lt;td&gt;~6-10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Philippines&lt;/td&gt;
&lt;td&gt;₱1,120&lt;/td&gt;
&lt;td&gt;~3-5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indonesia&lt;/td&gt;
&lt;td&gt;Rp320,000&lt;/td&gt;
&lt;td&gt;~4-7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;India&lt;/td&gt;
&lt;td&gt;₹1,600&lt;/td&gt;
&lt;td&gt;~2-4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pakistan&lt;/td&gt;
&lt;td&gt;PKR5,600&lt;/td&gt;
&lt;td&gt;~8-12%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brazil&lt;/td&gt;
&lt;td&gt;R$100&lt;/td&gt;
&lt;td&gt;~3-5%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a Nigerian developer, ChatGPT at $20/month is the equivalent of a US developer paying &lt;strong&gt;$400-600/month&lt;/strong&gt; for a productivity tool. They'd use workarounds too.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's actually happening
&lt;/h2&gt;

&lt;p&gt;Developers in price-sensitive markets are building impressive products — they're just doing it with one hand tied behind their backs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free tier cycling&lt;/strong&gt;: Creating multiple accounts to reset usage limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt compression&lt;/strong&gt;: Rewriting prompts to use fewer tokens, sacrificing quality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batching and delays&lt;/strong&gt;: Queuing requests to stay under rate limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing API keys&lt;/strong&gt;: Pooling costs across a team (violates ToS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local models&lt;/strong&gt;: Running Ollama on underpowered hardware (slow, worse quality)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of these is a workaround that burns developer time.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Africa tech story nobody's telling
&lt;/h2&gt;

&lt;p&gt;Nairobi has produced fintech infrastructure that the rest of the world is still catching up to. Lagos has a developer community that ships faster than most US startups. Cairo has engineering talent that's landing jobs at FAANG remotely.&lt;/p&gt;

&lt;p&gt;The African tech ecosystem isn't waiting for Silicon Valley's permission. But they are being &lt;strong&gt;priced out of AI tooling&lt;/strong&gt; that's now table stakes for competitive software development.&lt;/p&gt;

&lt;p&gt;Mpesa integration with AI? Lagos devs are building it.&lt;br&gt;
Multilingual chatbots for local languages? Nairobi devs are building it.&lt;br&gt;
Financial inclusion apps for unbanked populations? Accra devs are building it.&lt;/p&gt;

&lt;p&gt;All of them are paying the workaround tax.&lt;/p&gt;


&lt;h2&gt;
  
  
  What $2/month changes
&lt;/h2&gt;

&lt;p&gt;I've been running &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; — a Claude-powered AI assistant — at purchasing-power-parity pricing.&lt;/p&gt;

&lt;p&gt;For African developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🇳🇬 Nigeria: &lt;strong&gt;₦3,200/month&lt;/strong&gt; (vs ₦32,000+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇰🇪 Kenya: &lt;strong&gt;KSh260/month&lt;/strong&gt; (vs KSh2,600+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇬🇭 Ghana: &lt;strong&gt;GH₵25/month&lt;/strong&gt; (vs GH₵250+ for ChatGPT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a 10x price reduction. For a Nigerian developer, that's the difference between "I can't afford this" and "this costs less than my weekly phone data."&lt;/p&gt;


&lt;h2&gt;
  
  
  The API access story
&lt;/h2&gt;

&lt;p&gt;For developers who want to integrate AI into their apps, there's a REST API:&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;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: Bearer YOUR_KEY'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "Explain M-Pesa Daraja API integration"}'&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"M-Pesa Daraja API has three main integration points..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;312&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a Lagos developer building a WhatsApp bot for a client: the cost is fractions of a cent per message. Not hours of rate limit workarounds.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Silicon Valley gets wrong
&lt;/h2&gt;

&lt;p&gt;The assumption that "everyone" who matters is using the product is shaped by who's in the room when pricing decisions get made.&lt;/p&gt;

&lt;p&gt;The next wave of AI-native applications isn't going to be built in San Francisco. It's going to be built in Lagos, Nairobi, Jakarta, Manila, Karachi, and São Paulo — by developers who are currently spending 20% of their dev time on workarounds instead of shipping.&lt;/p&gt;

&lt;p&gt;Price parity isn't charity. It's recognizing that a developer in Kenya writing excellent code is creating exactly as much value as a developer in California writing excellent code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🇳🇬 Nigerian developers: &lt;a href="https://simplylouie.com/ng/" rel="noopener noreferrer"&gt;simplylouie.com/ng/&lt;/a&gt; — ₦3,200/month&lt;/li&gt;
&lt;li&gt;🇰🇪 Kenyan developers: &lt;a href="https://simplylouie.com/ke/" rel="noopener noreferrer"&gt;simplylouie.com/ke/&lt;/a&gt; — KSh260/month
&lt;/li&gt;
&lt;li&gt;🇬🇭 Ghana: &lt;a href="https://simplylouie.com/gh/" rel="noopener noreferrer"&gt;simplylouie.com/gh/&lt;/a&gt; — GH₵25/month&lt;/li&gt;
&lt;li&gt;🌍 All markets: &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt; — $2/month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;7-day free trial. No credit card required for the trial. Cancel anytime.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're a developer in Nigeria, Kenya, Ghana, or anywhere in Africa — I'd genuinely love to hear what you're building and what the AI tooling gap looks like from your side. Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>africa</category>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ChatGPT just raised prices again — here's how developers in emerging markets are responding</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 07:47:35 +0000</pubDate>
      <link>https://dev.to/subprime2010/chatgpt-just-raised-prices-again-heres-how-developers-in-emerging-markets-are-responding-50lm</link>
      <guid>https://dev.to/subprime2010/chatgpt-just-raised-prices-again-heres-how-developers-in-emerging-markets-are-responding-50lm</guid>
      <description>&lt;h1&gt;
  
  
  ChatGPT just raised prices again — here's how developers in emerging markets are responding
&lt;/h1&gt;

&lt;p&gt;Every time OpenAI or Anthropic tweaks their pricing, it barely registers for developers in San Francisco or London. A $5 increase is a rounding error.&lt;/p&gt;

&lt;p&gt;But for developers in Lagos, Karachi, Manila, or Dhaka? It's a different calculation entirely.&lt;/p&gt;

&lt;p&gt;Let me show you what I mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real cost of $20/month AI
&lt;/h2&gt;

&lt;p&gt;The monthly cost of ChatGPT Plus in local purchasing power terms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;ChatGPT $20/month&lt;/th&gt;
&lt;th&gt;Local equivalent&lt;/th&gt;
&lt;th&gt;Days of median salary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🇳🇬 Nigeria&lt;/td&gt;
&lt;td&gt;₦32,000&lt;/td&gt;
&lt;td&gt;≈ 4 days salary&lt;/td&gt;
&lt;td&gt;4 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇵🇰 Pakistan&lt;/td&gt;
&lt;td&gt;PKR 5,600&lt;/td&gt;
&lt;td&gt;≈ 3.5 days salary&lt;/td&gt;
&lt;td&gt;3.5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇵🇭 Philippines&lt;/td&gt;
&lt;td&gt;₱1,120&lt;/td&gt;
&lt;td&gt;≈ 1.5 days salary&lt;/td&gt;
&lt;td&gt;1.5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇧🇩 Bangladesh&lt;/td&gt;
&lt;td&gt;৳2,200&lt;/td&gt;
&lt;td&gt;≈ 2 days salary&lt;/td&gt;
&lt;td&gt;2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇰🇪 Kenya&lt;/td&gt;
&lt;td&gt;KSh 2,600&lt;/td&gt;
&lt;td&gt;≈ 1.5 days salary&lt;/td&gt;
&lt;td&gt;1.5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇬🇭 Ghana&lt;/td&gt;
&lt;td&gt;GH₵250&lt;/td&gt;
&lt;td&gt;≈ 2 days salary&lt;/td&gt;
&lt;td&gt;2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇮🇩 Indonesia&lt;/td&gt;
&lt;td&gt;Rp 320,000&lt;/td&gt;
&lt;td&gt;≈ 1.5 days salary&lt;/td&gt;
&lt;td&gt;1.5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🇮🇳 India&lt;/td&gt;
&lt;td&gt;₹1,600&lt;/td&gt;
&lt;td&gt;≈ 1 day salary&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a developer in Lagos, $20/month for AI isn't a productivity tool — it's a luxury subscription that competes with groceries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened when I talked to developers about this
&lt;/h2&gt;

&lt;p&gt;I've been running &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; — a $2/month Claude-powered AI — and the feedback from global users has been consistent:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"I was using the free tier of everything, copy-pasting between tools, because I couldn't justify $20/month."&lt;/strong&gt; — Developer in Karachi&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"ChatGPT costs more than my internet bill here. I was pirating API keys just to keep working."&lt;/strong&gt; — Freelancer in Manila&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"I needed AI for client work but the pricing made it impossible to factor into my rates."&lt;/strong&gt; — Consultant in Nairobi&lt;/p&gt;

&lt;p&gt;These aren't people who don't value AI. They value it enormously. They just can't afford the pricing model designed for Silicon Valley incomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical workaround everyone uses (and why it's unsustainable)
&lt;/h2&gt;

&lt;p&gt;Here's what actually happens in developer communities in emerging markets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API key sharing&lt;/strong&gt; — someone pays for an Anthropic key, shares it across 10 people. Violates ToS, gets revoked eventually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free tier abuse&lt;/strong&gt; — cycling through new accounts to maintain access to free tiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local models&lt;/strong&gt; — running Ollama or LM Studio locally. Works, but requires decent hardware and constant setup overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Going without&lt;/strong&gt; — using inferior free tools and accepting lower quality output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are sustainable. They're workarounds for a pricing problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What $2/month actually unlocks
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt;, the pricing is $2/month everywhere. Not $2/month in the US and $20/month everywhere else.&lt;/p&gt;

&lt;p&gt;Actual $2/month:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🇳🇬 Nigeria: ₦3,200/month (vs ₦32,000+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇵🇰 Pakistan: PKR 560/month (vs PKR 5,600+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇵🇭 Philippines: ₱112/month (vs ₱1,120+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇧🇩 Bangladesh: ৳220/month (vs ৳2,200+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇰🇪 Kenya: KSh 260/month (vs KSh 2,600+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇬🇭 Ghana: GH₵25/month (vs GH₵250+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇮🇩 Indonesia: Rp 32,000/month (vs Rp 320,000+ for ChatGPT)&lt;/li&gt;
&lt;li&gt;🇮🇳 India: ₹165/month (vs ₹1,600+ for ChatGPT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers in these markets, that's the difference between AI being a tool they use daily versus something they can't justify.&lt;/p&gt;

&lt;h2&gt;
  
  
  The developer API angle
&lt;/h2&gt;

&lt;p&gt;It's not just end-user chat. SimplyLouie also runs a developer API — full Claude access at a fraction of what Anthropic charges directly.&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;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "message": "Explain this function",
    "context": "I am a developer building a web app"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a freelance developer in Nairobi building client projects, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-assisted code review without burning budget&lt;/li&gt;
&lt;li&gt;Documentation generation at scale&lt;/li&gt;
&lt;li&gt;Client communication drafts in multiple languages&lt;/li&gt;
&lt;li&gt;All at a price point that makes sense as a business expense&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this matters beyond affordability
&lt;/h2&gt;

&lt;p&gt;The narrative that "AI will transform productivity globally" rings hollow when the tools are priced out of reach for 70% of the world's developers.&lt;/p&gt;

&lt;p&gt;Purchasing power parity pricing isn't charity — it's basic market access. The developer in Lagos is just as capable of building with AI as the developer in San Francisco. They just need tools priced for their market.&lt;/p&gt;

&lt;p&gt;The global developer community is enormous:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;India: ~5 million developers&lt;/li&gt;
&lt;li&gt;Nigeria: ~700,000 developers
&lt;/li&gt;
&lt;li&gt;Philippines: ~150,000 developers&lt;/li&gt;
&lt;li&gt;Indonesia: ~500,000 developers&lt;/li&gt;
&lt;li&gt;Pakistan: ~300,000 developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If AI tools remain priced at Silicon Valley rates, these developers — representing the next generation of global tech talent — get left behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually changing
&lt;/h2&gt;

&lt;p&gt;Some signals that this is shifting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Country-specific pricing&lt;/strong&gt; — more services are starting to offer local pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API democratization&lt;/strong&gt; — wrapper services making Claude/GPT accessible at lower price points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local AI communities&lt;/strong&gt; — Telegram groups, Discord servers, developer communities sharing resources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But the gap between what's available and what's affordable remains large.&lt;/p&gt;

&lt;h2&gt;
  
  
  For developers reading this from emerging markets
&lt;/h2&gt;

&lt;p&gt;You have options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SimplyLouie&lt;/strong&gt; — &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt; — $2/month everywhere, 7-day free trial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country-specific pages&lt;/strong&gt; for local pricing context: &lt;a href="https://simplylouie.com/in/" rel="noopener noreferrer"&gt;/in/&lt;/a&gt;, &lt;a href="https://simplylouie.com/ng/" rel="noopener noreferrer"&gt;/ng/&lt;/a&gt;, &lt;a href="https://simplylouie.com/ph/" rel="noopener noreferrer"&gt;/ph/&lt;/a&gt;, &lt;a href="https://simplylouie.com/ke/" rel="noopener noreferrer"&gt;/ke/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer API&lt;/strong&gt; for building with AI — &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;simplylouie.com/developers&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The 7-day free trial requires a card but doesn't charge for 7 days. Standard SaaS trial, cancel anytime.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;SimplyLouie is built on Claude (Anthropic). 50% of revenue goes to animal rescue. The ✌️$2/month price is intentional — AI shouldn't be a luxury.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're a developer in Nigeria, Pakistan, Philippines, Bangladesh, Kenya, Ghana, Indonesia, or India — this was written for you.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Why I stopped running local AI (Ollama, LM Studio) and switched to a $2/month API</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 06:47:50 +0000</pubDate>
      <link>https://dev.to/subprime2010/why-i-stopped-running-local-ai-ollama-lm-studio-and-switched-to-a-2month-api-2ke1</link>
      <guid>https://dev.to/subprime2010/why-i-stopped-running-local-ai-ollama-lm-studio-and-switched-to-a-2month-api-2ke1</guid>
      <description>&lt;h1&gt;
  
  
  Why I stopped running local AI (Ollama, LM Studio) and switched to a $2/month API
&lt;/h1&gt;

&lt;p&gt;I spent three months running local AI models. Ollama, LM Studio, llama.cpp — I tried them all. Last week I deleted them all and switched to a simple API call instead.&lt;/p&gt;

&lt;p&gt;Here's why.&lt;/p&gt;

&lt;h2&gt;
  
  
  The local AI dream vs. reality
&lt;/h2&gt;

&lt;p&gt;The pitch for local AI sounds perfect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No subscription fees&lt;/li&gt;
&lt;li&gt;No data leaving your machine&lt;/li&gt;
&lt;li&gt;Run it 24/7&lt;/li&gt;
&lt;li&gt;Works offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reality was different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: My laptop fan became a jet engine
&lt;/h2&gt;

&lt;p&gt;Running Llama 3 70B locally means your CPU/GPU is maxed out constantly. My 2021 MacBook Pro runs at 95°C during inference. The fans are audible across the room.&lt;/p&gt;

&lt;p&gt;For a quick question, I'm waiting 15-30 seconds for a response from a local 13B model. The same question on Claude takes 2 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 2: The quantization quality gap is real
&lt;/h2&gt;

&lt;p&gt;To run models locally, you have to use quantized versions (Q4, Q5, Q8). These are compressed versions that fit in RAM. But the quality difference between Q4_K_M Llama and the real Claude is... significant.&lt;/p&gt;

&lt;p&gt;For code generation especially, local models make subtle mistakes that are hard to catch. I spent an afternoon debugging a bug that a full-size model would have caught immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 3: Model updates are a nightmare
&lt;/h2&gt;

&lt;p&gt;Every few weeks there's a new model release. Pulling a 40GB model over my home internet takes 2+ hours. Then there's the GGUF format changes, the context length updates, the new quantization methods...&lt;/p&gt;

&lt;p&gt;Local AI is a part-time job if you want to stay current.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 4: RAM constraints mean you're always compromising
&lt;/h2&gt;

&lt;p&gt;I have 16GB RAM. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Llama 3 8B: OK but mediocre quality&lt;/li&gt;
&lt;li&gt;Llama 3 70B: Needs 48GB+ RAM, not happening&lt;/li&gt;
&lt;li&gt;Mistral 7B: Fits but limited capability&lt;/li&gt;
&lt;li&gt;Claude Sonnet: Not available locally at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontier models — the ones that actually do the hard work — aren't available locally at any price.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I switched to
&lt;/h2&gt;

&lt;p&gt;I now use &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; — a Claude API wrapper that costs $2/month.&lt;/p&gt;

&lt;p&gt;Here's my actual usage pattern:&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;# Old workflow: start Ollama, wait for model to load, get mediocre answer&lt;/span&gt;
ollama run llama3:70b &lt;span class="s2"&gt;"explain this bug"&lt;/span&gt; &lt;span class="c"&gt;# 45 seconds, 95°C CPU&lt;/span&gt;

&lt;span class="c"&gt;# New workflow: instant API call, full Claude quality&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "explain this bug"}'&lt;/span&gt;
&lt;span class="c"&gt;# 2 seconds, laptop stays cool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The math that convinced me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Local AI costs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Electricity: ~50W during inference × 2 hours/day = 3.6kWh/month = ~$0.50&lt;/li&gt;
&lt;li&gt;Hardware depreciation: Accelerated wear on CPU/GPU = hard to quantify but real&lt;/li&gt;
&lt;li&gt;Time cost: Model updates, troubleshooting, config management = 2-4 hours/month&lt;/li&gt;
&lt;li&gt;Quality: Using Q4 quantized models, not frontier quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;API costs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SimplyLouie: $2/month flat&lt;/li&gt;
&lt;li&gt;Full Claude Sonnet quality&lt;/li&gt;
&lt;li&gt;Zero maintenance&lt;/li&gt;
&lt;li&gt;Laptop stays cool and fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The break-even is obvious: if your time is worth anything at all, $2/month for API access beats the local AI overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  When local AI still makes sense
&lt;/h2&gt;

&lt;p&gt;I'm not saying local AI is always wrong. It makes sense when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You're processing truly sensitive data&lt;/strong&gt; that cannot leave your machine under any circumstances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're doing batch processing&lt;/strong&gt; of thousands of items and need to optimize cost at scale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're doing ML research&lt;/strong&gt; and need to fine-tune or inspect model weights&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're offline&lt;/strong&gt; and need AI without internet access&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the typical developer using AI for code review, documentation, debugging, and exploration — local AI adds friction without adding value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Stop Using Ollama" moment
&lt;/h2&gt;

&lt;p&gt;There's been a lot of discussion in the developer community about whether Ollama is the right tool for AI-assisted development. The honest answer: it depends on what you're trying to accomplish.&lt;/p&gt;

&lt;p&gt;If you're using Ollama because you think $20/month is too expensive — there's a better answer. $2/month gives you actual Claude access without the local model overhead.&lt;/p&gt;

&lt;p&gt;If you're using Ollama because you're worried about privacy — that's more legitimate, though a well-run API service with no training on your data addresses most privacy concerns.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API setup takes 2 minutes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Install nothing. No Ollama, no LM Studio, no GGUF files.&lt;/span&gt;
&lt;span class="c1"&gt;// Just this:&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://simplylouie.com/api/chat&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bearer YOUR_API_KEY&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;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;message&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 this code for security vulnerabilities&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yourCodeHere&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reply&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;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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Claude-quality response in ~2 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No model downloads. No RAM constraints. No thermal throttling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it free for 7 days
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie.com&lt;/a&gt; — $2/month after a 7-day free trial. No credit card games, just a simple flat rate.&lt;/p&gt;

&lt;p&gt;For developers in emerging markets: the same API is available at local pricing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;India: Rs165/month → &lt;a href="https://simplylouie.com/in/" rel="noopener noreferrer"&gt;simplylouie.com/in/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nigeria: N3,200/month → &lt;a href="https://simplylouie.com/ng/" rel="noopener noreferrer"&gt;simplylouie.com/ng/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Philippines: P112/month → &lt;a href="https://simplylouie.com/ph/" rel="noopener noreferrer"&gt;simplylouie.com/ph/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Indonesia: Rp32,000/month → &lt;a href="https://simplylouie.com/id/" rel="noopener noreferrer"&gt;simplylouie.com/id/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I deleted Ollama 3 weeks ago. I don't miss it.&lt;/p&gt;

</description>
      <category>ollama</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why developers in emerging markets can't afford Claude — and what I built instead</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 05:47:30 +0000</pubDate>
      <link>https://dev.to/subprime2010/why-developers-in-emerging-markets-cant-afford-claude-and-what-i-built-instead-2pg9</link>
      <guid>https://dev.to/subprime2010/why-developers-in-emerging-markets-cant-afford-claude-and-what-i-built-instead-2pg9</guid>
      <description>&lt;h1&gt;
  
  
  Why developers in emerging markets can't afford Claude — and what I built instead
&lt;/h1&gt;

&lt;p&gt;I've been thinking about the gap between AI pricing and global developer salaries.&lt;/p&gt;

&lt;p&gt;A junior developer in Lagos earns roughly $300-500/month. ChatGPT Plus costs $20/month. That's &lt;strong&gt;4-7% of their monthly salary&lt;/strong&gt; just for an AI assistant.&lt;/p&gt;

&lt;p&gt;In the US, $20/month is 2 coffee runs. In Nigeria, it's a week of groceries.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers that changed how I think about AI pricing
&lt;/h2&gt;

&lt;p&gt;Let me show you the real cost of $20/month AI in purchasing power terms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;ChatGPT cost&lt;/th&gt;
&lt;th&gt;Local equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nigeria&lt;/td&gt;
&lt;td&gt;N32,000/month&lt;/td&gt;
&lt;td&gt;~4 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Philippines&lt;/td&gt;
&lt;td&gt;P1,120/month&lt;/td&gt;
&lt;td&gt;~2 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kenya&lt;/td&gt;
&lt;td&gt;KSh2,600/month&lt;/td&gt;
&lt;td&gt;~3 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pakistan&lt;/td&gt;
&lt;td&gt;PKR5,600/month&lt;/td&gt;
&lt;td&gt;~3 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indonesia&lt;/td&gt;
&lt;td&gt;Rp320,000/month&lt;/td&gt;
&lt;td&gt;~3 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;India&lt;/td&gt;
&lt;td&gt;Rs1,600/month&lt;/td&gt;
&lt;td&gt;~2 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brazil&lt;/td&gt;
&lt;td&gt;R$100/month&lt;/td&gt;
&lt;td&gt;~1.5 days of avg wages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This isn't an abstract pricing complaint. It means millions of talented developers are locked out of tools that their counterparts in San Francisco use without thinking twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like in practice
&lt;/h2&gt;

&lt;p&gt;I've talked to developers in these markets. The pattern is consistent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They use the free tier until they hit limits&lt;/li&gt;
&lt;li&gt;They share accounts (against ToS) to split costs&lt;/li&gt;
&lt;li&gt;They use inferior tools that don't require payment&lt;/li&gt;
&lt;li&gt;They churn off paid plans when money is tight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The worst part? These are exactly the developers who could benefit most. They're often working on solutions for their local markets — fintech apps for mobile money, healthcare tools for underserved clinics, agricultural tech for smallholder farmers. AI would genuinely multiply their impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture problem
&lt;/h2&gt;

&lt;p&gt;Here's what I think the real issue is: the big AI companies are building for one market.&lt;/p&gt;

&lt;p&gt;Their pricing is set by US purchasing power. Their payment methods assume credit cards. Their marketing is in English. Their examples are about startups in California.&lt;/p&gt;

&lt;p&gt;This isn't malicious — it's just that you optimize for your existing customer base.&lt;/p&gt;

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

&lt;p&gt;I built &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; as a direct response to this.&lt;/p&gt;

&lt;p&gt;The core idea: Claude API access at a price that makes sense globally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;India: Rs165/month (&lt;a href="https://simplylouie.com/in/" rel="noopener noreferrer"&gt;simplylouie.com/in/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Nigeria: N3,200/month (&lt;a href="https://simplylouie.com/ng/" rel="noopener noreferrer"&gt;simplylouie.com/ng/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Philippines: P112/month (&lt;a href="https://simplylouie.com/ph/" rel="noopener noreferrer"&gt;simplylouie.com/ph/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Kenya: KSh260/month (&lt;a href="https://simplylouie.com/ke/" rel="noopener noreferrer"&gt;simplylouie.com/ke/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ghana: GH¢25/month (&lt;a href="https://simplylouie.com/gh/" rel="noopener noreferrer"&gt;simplylouie.com/gh/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Indonesia: Rp32,000/month (&lt;a href="https://simplylouie.com/id/" rel="noopener noreferrer"&gt;simplylouie.com/id/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Brazil: R$10/month (&lt;a href="https://simplylouie.com/br/" rel="noopener noreferrer"&gt;simplylouie.com/br/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Mexico: MX$35/month (&lt;a href="https://simplylouie.com/mx/" rel="noopener noreferrer"&gt;simplylouie.com/mx/&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The global base price is $2/month. Not a free tier with limits. Not a "starter plan" that gatekeeps the real features. Just $2.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API, for developers
&lt;/h2&gt;

&lt;p&gt;For developers who want to build with this, there's also a developer API tier. Here's what it looks like:&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;# Get your API key from simplylouie.com/developers&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LOUIE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;

curl https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$LOUIE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "message": "Explain this code: $(cat main.py | head -50)",
    "model": "claude-3-5-haiku-20241022"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real Claude API responses. No rate limit theater. $10/month for the API tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned building this
&lt;/h2&gt;

&lt;p&gt;The most interesting thing I discovered: when you price for global markets, you have to rethink everything.&lt;/p&gt;

&lt;p&gt;Payment methods: M-Pesa in Kenya, UPI in India, Pix in Brazil. Credit cards are not universal.&lt;/p&gt;

&lt;p&gt;Language: Portuguese for Brazil, Tagalog phrases for the Philippines. English-only is a conversion killer.&lt;/p&gt;

&lt;p&gt;Examples: The use cases that resonate in Lagos are different from those in London. "Write my performance review" lands differently when the developer is working for a US startup remotely vs. a local company.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that matters most
&lt;/h2&gt;

&lt;p&gt;50% of SimplyLouie's revenue goes to animal rescue.&lt;/p&gt;

&lt;p&gt;That's not a marketing line — it's a constraint I built in from the start. The business model only works if the pricing is accessible, which keeps me honest about not raising prices.&lt;/p&gt;




&lt;p&gt;If you're a developer in one of these markets, I'd genuinely love to know what you're building and whether the price point makes a difference. That's the only way I learn if this is actually working.&lt;/p&gt;

&lt;p&gt;And if you're a developer in a high-income market reading this: consider that the tools you take for granted are luxuries elsewhere. The ecosystem benefits when more people can participate.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;SimplyLouie is live at &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt;. 7-day free trial, no credit card games.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Your AI conversations are being used against you — here's the $2/month alternative</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 00:52:44 +0000</pubDate>
      <link>https://dev.to/subprime2010/your-ai-conversations-are-being-used-against-you-heres-the-2month-alternative-4icb</link>
      <guid>https://dev.to/subprime2010/your-ai-conversations-are-being-used-against-you-heres-the-2month-alternative-4icb</guid>
      <description>&lt;h1&gt;
  
  
  Your AI conversations are being used against you
&lt;/h1&gt;

&lt;p&gt;You've seen the news: &lt;a href="https://www.eff.org/deeplinks/2026/04/google-broke-its-promise-me-now-ice-has-my-data" rel="noopener noreferrer"&gt;Google broke its promise to a user, and now ICE has their data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;HN front page. 1000+ points. 460 comments. The developer community is furious.&lt;/p&gt;

&lt;p&gt;And here's the uncomfortable question nobody wants to ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to your ChatGPT conversations?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you're actually agreeing to
&lt;/h2&gt;

&lt;p&gt;When you use ChatGPT, you're sending your:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code you're debugging&lt;/li&gt;
&lt;li&gt;Business ideas you're exploring
&lt;/li&gt;
&lt;li&gt;Personal problems you're working through&lt;/li&gt;
&lt;li&gt;Work documents you're summarizing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...to a company that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trains on your conversations by default&lt;/li&gt;
&lt;li&gt;Has responded to government requests&lt;/li&gt;
&lt;li&gt;Can change its privacy policy at any time&lt;/li&gt;
&lt;li&gt;Charges you $20/month for the privilege&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The power user problem
&lt;/h2&gt;

&lt;p&gt;Developers are the highest-risk group here. We're putting the most sensitive stuff into AI:&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;# You're asking about your company's internal architecture&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.openai.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"messages": [{"role": "user", "content": "Here is our production database schema: [your schema]"}]}'&lt;/span&gt;

&lt;span class="c"&gt;# Your code review requests contain your IP&lt;/span&gt;
curl ... &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"content": "Review this unreleased feature: [your feature code]"}'&lt;/span&gt;

&lt;span class="c"&gt;# Your debugging sessions reveal your infrastructure&lt;/span&gt;
curl ... &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"content": "Why is this crashing on our AWS us-east-1 deployment?"}'&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every one of these conversations is stored, processed, potentially used for training.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API is different
&lt;/h2&gt;

&lt;p&gt;Here's something most developers don't know: when you use the &lt;strong&gt;API directly&lt;/strong&gt;, the data handling policies are different. API calls are not used for model training by default.&lt;/p&gt;

&lt;p&gt;But the API costs money. Big money.&lt;/p&gt;

&lt;p&gt;Anthropic charges by token. At scale, that gets expensive fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I use instead
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; — $2/month flat for Claude API access.&lt;/p&gt;

&lt;p&gt;Here's the actual curl command:&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;# Sign up at simplylouie.com, get your API key&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LOUIE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;

&lt;span class="c"&gt;# Same Claude, but $2/month flat — not $20/month, not token-by-token billing&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$LOUIE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "messages": [
      {"role": "user", "content": "Review this code: [your code]"}
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. 2 dollars a month. Same Claude model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math on trust
&lt;/h2&gt;

&lt;p&gt;When a service is free or cheap, you're not the customer — you're the product.&lt;/p&gt;

&lt;p&gt;When a service is $20/month, you're paying for... the same risk, just with a higher monthly bill.&lt;/p&gt;

&lt;p&gt;When a service is $2/month with API key access:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're actually paying for the compute&lt;/li&gt;
&lt;li&gt;There's a direct transaction&lt;/li&gt;
&lt;li&gt;No ad revenue model to feed&lt;/li&gt;
&lt;li&gt;No pressure to monetize your conversations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  For developers outside the US
&lt;/h2&gt;

&lt;p&gt;This matters even more if you're not in the US. Government data requests don't just come from the American government.&lt;/p&gt;

&lt;p&gt;If you're in India, Nigeria, Philippines, Indonesia, Kenya, Brazil, Pakistan, or anywhere with a government that pressures tech companies — the centralization of your conversations in a US-based AI company is a real risk.&lt;/p&gt;

&lt;p&gt;SimplyLouie has country-specific pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🇮🇳 &lt;a href="https://simplylouie.com/in/" rel="noopener noreferrer"&gt;India — Rs165/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇳🇬 &lt;a href="https://simplylouie.com/ng/" rel="noopener noreferrer"&gt;Nigeria — N3,200/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇵🇭 &lt;a href="https://simplylouie.com/ph/" rel="noopener noreferrer"&gt;Philippines — P112/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇮🇩 &lt;a href="https://simplylouie.com/id/" rel="noopener noreferrer"&gt;Indonesia — Rp32,000/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇰🇪 &lt;a href="https://simplylouie.com/ke/" rel="noopener noreferrer"&gt;Kenya — KSh260/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇧🇷 &lt;a href="https://simplylouie.com/br/" rel="noopener noreferrer"&gt;Brazil — R$10/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇲🇽 &lt;a href="https://simplylouie.com/mx/" rel="noopener noreferrer"&gt;Mexico — MX$35/month&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🇵🇰 &lt;a href="https://simplylouie.com/pk/" rel="noopener noreferrer"&gt;Pakistan — Rs560/month&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;The Google/ICE story broke something today. Developers are realizing that "cloud services" means "someone else has your data, indefinitely, subject to legal requests you'll never know about."&lt;/p&gt;

&lt;p&gt;You can't fully opt out of the cloud. But you can make better choices about which companies hold your most sensitive professional data.&lt;/p&gt;

&lt;p&gt;For AI: $2/month, API access, flat billing. &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;SimplyLouie is a $2/month Claude API service. 50% of revenue goes to animal rescue. We don't train on your conversations.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>ai</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>ChatGPT costs PKR 5,600/month in Pakistan — here's the ₨560 alternative</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Thu, 16 Apr 2026 00:34:25 +0000</pubDate>
      <link>https://dev.to/subprime2010/chatgpt-costs-pkr-5600month-in-pakistan-heres-the-rs560-alternative-4dmb</link>
      <guid>https://dev.to/subprime2010/chatgpt-costs-pkr-5600month-in-pakistan-heres-the-rs560-alternative-4dmb</guid>
      <description>&lt;h1&gt;
  
  
  ChatGPT costs PKR 5,600/month in Pakistan — here's the ₨560 alternative
&lt;/h1&gt;

&lt;p&gt;Let me put that number in context.&lt;/p&gt;

&lt;p&gt;PKR 5,600/month for ChatGPT Plus. That's roughly the cost of 3-4 days of groceries for a family. It's more than many junior developers earn in a week at a local company.&lt;/p&gt;

&lt;p&gt;For a freelancer in Lahore, Karachi, or Islamabad trying to use AI to compete with developers in the West — that price is simply not accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math that kills it
&lt;/h2&gt;

&lt;p&gt;The average software developer salary in Pakistan is around PKR 80,000–120,000/month. ChatGPT at PKR 5,600 is &lt;strong&gt;5-7% of your monthly salary&lt;/strong&gt; — just for one AI tool.&lt;/p&gt;

&lt;p&gt;Compare that to a US developer earning $8,000/month paying $20 — that's 0.25% of their salary.&lt;/p&gt;

&lt;p&gt;Same product. 20-28x the proportional cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I use instead
&lt;/h2&gt;

&lt;p&gt;I found &lt;a href="https://simplylouie.com/pk/" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt; — it runs on Claude (the same model behind Claude.ai and Claude Code) and costs &lt;strong&gt;PKR 560/month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's 1/10th the price of ChatGPT.&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;# Quick test with the developer API&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "Review this Python function for bugs", "model": "claude-haiku"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LUMS/FAST/NUST CS students&lt;/strong&gt; — using AI for assignments, projects, thesis work. PKR 560 is less than a chai and samosa run for a week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upwork/Fiverr freelancers in Karachi/Lahore&lt;/strong&gt; — you're competing with developers worldwide. AI assistance is table stakes. At PKR 560, it pays for itself with one extra task completed per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Startup developers in DHA Karachi or F-7 Islamabad&lt;/strong&gt; — building products with tight budgets. The developer API tier means you can integrate AI into your product without burning through a $20/month personal account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arfa Software Technology Park developers in Lahore&lt;/strong&gt; — the largest IT park in Pakistan, thousands of developers. If you're there and not using AI yet, this is the entry point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical difference
&lt;/h2&gt;

&lt;p&gt;SimplyLouie uses Claude Haiku — Anthropic's fastest model. For most developer tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code review ✅&lt;/li&gt;
&lt;li&gt;Writing documentation ✅
&lt;/li&gt;
&lt;li&gt;Debugging Python/JS/PHP ✅&lt;/li&gt;
&lt;li&gt;Answering Stack Overflow-style questions ✅&lt;/li&gt;
&lt;li&gt;Drafting client emails in professional English ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For deep reasoning tasks, there's a developer API tier that gives you direct access to more powerful models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm writing this
&lt;/h2&gt;

&lt;p&gt;I got tired of seeing Pakistani developers locked out of tools that developers in richer countries take for granted.&lt;/p&gt;

&lt;p&gt;The skill gap isn't the problem. The price gap is the problem.&lt;/p&gt;

&lt;p&gt;PKR 560/month removes that barrier.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it free for 7 days&lt;/strong&gt; at &lt;a href="https://simplylouie.com/pk/" rel="noopener noreferrer"&gt;simplylouie.com/pk/&lt;/a&gt; — no credit card required to start.&lt;/p&gt;

&lt;p&gt;If you're a Pakistani developer using AI tools, drop a comment. What's your biggest use case?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #pakistan #artificialintelligence #webdev #programming&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pakistan</category>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building a voice-activated AI assistant with Node.js and Claude API</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Wed, 15 Apr 2026 22:34:34 +0000</pubDate>
      <link>https://dev.to/subprime2010/building-a-voice-activated-ai-assistant-with-nodejs-and-claude-api-4ip4</link>
      <guid>https://dev.to/subprime2010/building-a-voice-activated-ai-assistant-with-nodejs-and-claude-api-4ip4</guid>
      <description>&lt;h1&gt;
  
  
  Building a voice-activated AI assistant with Node.js and Claude API
&lt;/h1&gt;

&lt;p&gt;I wanted to build something fun: a voice assistant that actually understands context, remembers what you said earlier in the conversation, and costs less than a coffee a month to run.&lt;/p&gt;

&lt;p&gt;Here's how I built it using the Web Speech API + Node.js + Claude API access via &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;SimplyLouie&lt;/a&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Vanilla JS + Web Speech API (built into Chrome/Edge — no library needed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Node.js Express&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI&lt;/strong&gt;: Claude via SimplyLouie's developer API at $10/month flat&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt;: In-memory conversation history (upgradeable to Redis)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: The frontend — capture voice input
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Voice AI&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"startBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🎤 Hold to talk&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"transcript"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"response"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;startBtn&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;transcriptEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transcript&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;responseEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&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;recognition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;webkitSpeechRecognition&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;continuous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interimResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mousedown&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="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseup&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="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onresult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;transcriptEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`You said: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transcript&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;reply&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;/api/chat&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;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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;transcript&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&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="nx"&gt;responseEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`AI: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&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="c1"&gt;// Speak the response back&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;utterance&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;SpeechSynthesisUtterance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speechSynthesis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;utterance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: The backend — handle conversation context
&lt;/h2&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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="c1"&gt;// Simple in-memory conversation store (keyed by session)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conversations&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;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="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;sessionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-session-id&lt;/span&gt;&lt;span class="dl"&gt;'&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;default&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Get or create conversation history&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;conversations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Add user message&lt;/span&gt;
  &lt;span class="nx"&gt;history&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="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;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Keep last 10 exchanges to stay within context limits&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recentHistory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&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://simplylouie.com/api/chat&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;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="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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOUIE_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;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;recentHistory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;system&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 are a helpful voice assistant. Keep responses concise — under 2 sentences when possible, since they will be read aloud.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aiReply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&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="c1"&gt;// Store assistant response&lt;/span&gt;
    &lt;span class="nx"&gt;history&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="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;assistant&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;aiReply&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;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;aiReply&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&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="na"&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;AI unavailable&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Voice AI running on :3000&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;h2&gt;
  
  
  Step 3: Add session tracking so it remembers the conversation
&lt;/h2&gt;

&lt;p&gt;The frontend needs to send a consistent session ID:&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;// Add to frontend — generate once per page load&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&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="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Update the fetch call:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reply&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;/api/chat&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-session-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sessionId&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;lt;-- add this&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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;transcript&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it remembers what you talked about earlier in the session.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it can do
&lt;/h2&gt;

&lt;p&gt;Once it's running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: "What's the capital of France?"
AI: "Paris."

You: "What's the population there?"
AI: "Paris has about 2.1 million people in the city proper."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how the second question works — it understands "there" means Paris because of the conversation history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost math
&lt;/h2&gt;

&lt;p&gt;I ran this for a week with about 200 voice interactions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude API via SimplyLouie: &lt;strong&gt;$10/month flat&lt;/strong&gt; (developer tier)&lt;/li&gt;
&lt;li&gt;Hosting (Railway): &lt;strong&gt;$5/month&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Web Speech API: &lt;strong&gt;free&lt;/strong&gt; (browser built-in)&lt;/li&gt;
&lt;li&gt;Total: &lt;strong&gt;$15/month&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For comparison, building this with OpenAI's Whisper for speech-to-text + GPT-4 API would run $40-60/month at the same volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional: add wake word detection
&lt;/h2&gt;

&lt;p&gt;If you want it to always listen (like Alexa):&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;// Continuously restart recognition&lt;/span&gt;
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onend&lt;/span&gt; &lt;span class="o"&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isListening&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onresult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Only respond if wake word detected&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;transcript&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;hey louie&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="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actualMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hey louie&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="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// ... rest of handler&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isListening&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;The developer API that powers this: &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;simplylouie.com/developers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$10/month flat rate. No per-token billing surprises. You hit the API, it works.&lt;/p&gt;

&lt;p&gt;Full repo for this project is in the comments — drop your questions there too.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ai</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>How I use Claude to write better commit messages (with a git hook)</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Wed, 15 Apr 2026 20:34:32 +0000</pubDate>
      <link>https://dev.to/subprime2010/how-i-use-claude-to-write-better-commit-messages-with-a-git-hook-4jag</link>
      <guid>https://dev.to/subprime2010/how-i-use-claude-to-write-better-commit-messages-with-a-git-hook-4jag</guid>
      <description>&lt;h1&gt;
  
  
  How I use Claude to write better commit messages (with a git hook)
&lt;/h1&gt;

&lt;p&gt;Every developer knows the pain: you've just fixed a gnarly bug at 11pm, and git is waiting for a commit message. You type &lt;code&gt;fix stuff&lt;/code&gt; and move on.&lt;/p&gt;

&lt;p&gt;I fixed this with a git hook that calls the Claude API to generate a meaningful commit message from my diff — automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with manual commit messages
&lt;/h2&gt;

&lt;p&gt;Bad commit messages are a tax you pay in the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fix bug&lt;/code&gt; — which bug? Fixed how?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WIP&lt;/code&gt; — why is this in main?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;asdfasdf&lt;/code&gt; — we've all been there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good commit messages are like documentation that writes itself — &lt;em&gt;if&lt;/em&gt; you have the discipline to write them at 11pm. Most of us don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution: a &lt;code&gt;prepare-commit-msg&lt;/code&gt; git hook
&lt;/h2&gt;

&lt;p&gt;Git has a hook called &lt;code&gt;prepare-commit-msg&lt;/code&gt; that runs before your editor opens. It can pre-populate the commit message. This is perfect for AI generation.&lt;/p&gt;

&lt;p&gt;Here's the hook I use:&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;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# .git/hooks/prepare-commit-msg&lt;/span&gt;

&lt;span class="nv"&gt;COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;COMMIT_SOURCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;

&lt;span class="c"&gt;# Only auto-generate for normal commits (not merges, amends, etc)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_SOURCE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Get the diff of staged changes&lt;/span&gt;
&lt;span class="nv"&gt;DIFF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--stat&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;DIFF_CONTENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DIFF&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Call the API&lt;/span&gt;
&lt;span class="nv"&gt;RESPONSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: &lt;/span&gt;&lt;span class="nv"&gt;$LOUIE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--arg&lt;/span&gt; diff &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DIFF&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--arg&lt;/span&gt; content &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DIFF_CONTENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s1"&gt;'{message: ("Write a concise git commit message (under 72 chars) for these changes. Use conventional commits format (feat/fix/refactor/docs/chore). Just the message, no explanation.\n\nStat:\n" + $diff + "\n\nDiff (first 100 lines):\n" + $content)}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; 

&lt;span class="nv"&gt;MESSAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$RESPONSE&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.response // empty'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# AI-generated. Edit if needed."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it executable:&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="nb"&gt;chmod&lt;/span&gt; +x .git/hooks/prepare-commit-msg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set your 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;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LOUIE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key_here
&lt;span class="c"&gt;# Add to ~/.bashrc or ~/.zshrc to make permanent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real examples from my workflow
&lt;/h2&gt;

&lt;p&gt;Before (what I'd have typed at 11pm):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix auth thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After (AI-generated from the same diff):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix: resolve JWT expiry race condition in token refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before: update stuff
after:  refactor: extract UserRepository from UserService, add unit tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hook sees exactly what changed. It generates messages that are actually useful 6 months later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it a global git hook
&lt;/h2&gt;

&lt;p&gt;If you want this in every repo, not just one:&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="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.git-hooks
&lt;span class="nb"&gt;cp&lt;/span&gt; .git/hooks/prepare-commit-msg ~/.git-hooks/
git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.hooksPath ~/.git-hooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now every repo on your machine gets AI commit messages automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;SimplyLouie's API&lt;/a&gt; — it's $2/month for unlimited access, which means this hook costs effectively $0 per commit. I run it probably 20-30 times a day.&lt;/p&gt;

&lt;p&gt;If you're calling Anthropic directly, each commit message is maybe 500 input tokens + 50 output tokens. At $3/million input tokens, that's $0.0015 per commit. Still cheap, but it adds up if you're committing constantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending it
&lt;/h2&gt;

&lt;p&gt;This same pattern works for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR descriptions&lt;/strong&gt; — run the diff through the same API when you open a PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff main...HEAD | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-200&lt;/span&gt; | curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: &lt;/span&gt;&lt;span class="nv"&gt;$LOUIE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "Write a PR description for this diff"}'&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.response'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Changelog generation&lt;/strong&gt; — at release time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log v1.0..HEAD &lt;span class="nt"&gt;--oneline&lt;/span&gt; | curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: &lt;/span&gt;&lt;span class="nv"&gt;$LOUIE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Convert these commits to a user-friendly changelog:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git log v1.0..HEAD &lt;span class="nt"&gt;--oneline&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get the API key
&lt;/h2&gt;

&lt;p&gt;You need a SimplyLouie API key to run this. Sign up at &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;simplylouie.com&lt;/a&gt; — it's $2/month, the API is included.&lt;/p&gt;

&lt;p&gt;Or adapt the hook to use any OpenAI-compatible API endpoint — the JSON format is standard.&lt;/p&gt;




&lt;p&gt;What's your current commit message workflow? Drop it in the comments — I'm curious how many people are still typing &lt;code&gt;fix stuff&lt;/code&gt; at 11pm.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>How I built a multi-language AI chatbot for $2/month (full code walkthrough)</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Wed, 15 Apr 2026 18:34:28 +0000</pubDate>
      <link>https://dev.to/subprime2010/how-i-built-a-multi-language-ai-chatbot-for-2month-full-code-walkthrough-1i09</link>
      <guid>https://dev.to/subprime2010/how-i-built-a-multi-language-ai-chatbot-for-2month-full-code-walkthrough-1i09</guid>
      <description>&lt;h1&gt;
  
  
  How I built a multi-language AI chatbot for $2/month (full code walkthrough)
&lt;/h1&gt;

&lt;p&gt;I needed a chatbot that could handle English, Spanish, Portuguese, and Tagalog for different user segments. My first instinct was to use the OpenAI API directly. Then I saw the bill.&lt;/p&gt;

&lt;p&gt;Here's how I ended up building the same thing for about $2/month total — and what I learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with rolling your own API access
&lt;/h2&gt;

&lt;p&gt;When you call Claude or GPT directly, you pay per token. That sounds cheap until you realize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A single conversation of 10 messages ≈ 2,000-4,000 tokens&lt;/li&gt;
&lt;li&gt;1,000 conversations/month = 2-4 million tokens&lt;/li&gt;
&lt;li&gt;At $3/million tokens for Claude Sonnet, that's $6-12 just in API costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a side project with uncertain traffic, that unpredictability is painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture I used
&lt;/h2&gt;

&lt;p&gt;Instead of managing API keys, rate limits, and billing myself, I proxied everything through &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;SimplyLouie's developer API&lt;/a&gt; — a flat $10/month tier that handles all the Claude API access.&lt;/p&gt;

&lt;p&gt;Here's the full setup:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Backend handler (Node.js)
&lt;/h3&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LOUIE_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOUIE_API_KEY&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;SUPPORTED_LANGUAGES&lt;/span&gt; &lt;span class="o"&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;en&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;es&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;pt&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;tl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Detect language from user message&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;detectLanguage&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;response&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;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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://simplylouie.com/api/chat&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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Detect the language of this text and respond with only the 2-letter ISO code (en, es, pt, tl, etc): "&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="s2"&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;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;LOUIE_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="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&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;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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;SUPPORTED_LANGUAGES&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="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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="c1"&gt;// System prompts by language&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SYSTEM_PROMPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;en&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 are a helpful assistant. Respond in English.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Eres un asistente útil. Responde en español.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Você é um assistente prestativo. Responda em português.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ikaw ay isang kapaki-pakinabang na katulong. Sumagot sa Filipino.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Auto-detect language&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lang&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;detectLanguage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Send to Claude via SimplyLouie proxy&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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://simplylouie.com/api/chat&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;message&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="nx"&gt;SYSTEM_PROMPTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nx"&gt;sessionId&lt;/span&gt;
  &lt;span class="p"&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;LOUIE_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="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;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;detectedLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Simple frontend (React)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useState&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MultiLanguageChat&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="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="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&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;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;sessionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&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="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="mi"&gt;0&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;sendMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="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;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&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;userMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setInput&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="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userMessage&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/chat&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;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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionId&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;data&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;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&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;assistant&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detectedLanguage&lt;/span&gt;
    &lt;span class="p"&gt;}]);&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"chat-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`message &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"lang-badge"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Thinking...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"input-area"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onKeyPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Type in any language..."&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;h3&gt;
  
  
  3. Deploy with Docker
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;chatbot&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LOUIE_API_KEY=${LOUIE_API_KEY}&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this costs at scale
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Users/month&lt;/th&gt;
&lt;th&gt;My infra cost&lt;/th&gt;
&lt;th&gt;API cost&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;$5 (VPS)&lt;/td&gt;
&lt;td&gt;$10 (flat)&lt;/td&gt;
&lt;td&gt;$15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;$5 (VPS)&lt;/td&gt;
&lt;td&gt;$10 (flat)&lt;/td&gt;
&lt;td&gt;$15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;$20 (VPS)&lt;/td&gt;
&lt;td&gt;$10 (flat)&lt;/td&gt;
&lt;td&gt;$30&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The flat-rate API means the chatbot cost doesn't scale with usage — only my infrastructure does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language performance notes
&lt;/h2&gt;

&lt;p&gt;After running this for a few weeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;English&lt;/strong&gt;: Near-perfect, as expected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spanish&lt;/strong&gt;: Excellent — Claude handles Latin American variants naturally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portuguese (Brazil)&lt;/strong&gt;: Very good — just specify "Brazilian Portuguese" in the system prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tagalog/Filipino&lt;/strong&gt;: Good for common phrases, occasionally switches to English for technical terms (which is actually how Filipino speakers naturally talk)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The part that surprised me
&lt;/h2&gt;

&lt;p&gt;The language detection step (the extra API call to identify the language) adds ~200ms of latency. For most use cases this is fine, but if you need real-time responsiveness, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use a lightweight local library like &lt;code&gt;franc&lt;/code&gt; for detection (no API call)&lt;/li&gt;
&lt;li&gt;Let the user select their language upfront&lt;/li&gt;
&lt;li&gt;Detect from browser &lt;code&gt;Accept-Language&lt;/code&gt; header&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I went with option 1 for production — &lt;code&gt;franc&lt;/code&gt; adds a few KB to the bundle but saves 200ms per message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;If you want to build something similar, the developer API is at &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;simplylouie.com/developers&lt;/a&gt;. $10/month flat, no per-token surprises.&lt;/p&gt;

&lt;p&gt;If you just want the chatbot without the API layer, there's also a &lt;a href="https://simplylouie.com" rel="noopener noreferrer"&gt;personal plan at $2/month&lt;/a&gt; — the most affordable AI assistant I've found.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What languages are you building AI features for? Drop a comment — I'm curious what's working for people outside the English-speaking world.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ai</category>
      <category>node</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How I use AI subagents to parallelize my development workflow</title>
      <dc:creator>brian austin</dc:creator>
      <pubDate>Wed, 15 Apr 2026 17:34:36 +0000</pubDate>
      <link>https://dev.to/subprime2010/how-i-use-ai-subagents-to-parallelize-my-development-workflow-1e8m</link>
      <guid>https://dev.to/subprime2010/how-i-use-ai-subagents-to-parallelize-my-development-workflow-1e8m</guid>
      <description>&lt;h1&gt;
  
  
  How I use AI subagents to parallelize my development workflow
&lt;/h1&gt;

&lt;p&gt;For most of my career, I treated AI assistants as single-threaded: one prompt, one response, one task at a time.&lt;/p&gt;

&lt;p&gt;Then I started using subagents. Now I run 3-4 parallel AI tasks simultaneously and ship features in half the time.&lt;/p&gt;

&lt;p&gt;Here's exactly how my workflow looks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with single-threaded AI
&lt;/h2&gt;

&lt;p&gt;When you have a big feature to ship — say, "add payment processing" — the naive approach is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask AI to write the backend&lt;/li&gt;
&lt;li&gt;Wait&lt;/li&gt;
&lt;li&gt;Ask AI to write the frontend&lt;/li&gt;
&lt;li&gt;Wait&lt;/li&gt;
&lt;li&gt;Ask AI to write the tests&lt;/li&gt;
&lt;li&gt;Wait&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total time: 3 AI sessions × 10 minutes each = 30 minutes minimum, and you're context-switching constantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The subagent approach
&lt;/h2&gt;

&lt;p&gt;With subagents, I decompose the work first, then run tasks in parallel:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session 1 (backend):&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="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;handling&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;Stripe&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="nx"&gt;integration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;payments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;only&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Write&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="nx"&gt;handlers&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;Stripe&lt;/span&gt; &lt;span class="nx"&gt;webhook&lt;/span&gt; &lt;span class="nx"&gt;processing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Session 2 (frontend):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;handling&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;frontend&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="nx"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;PaymentForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="nx"&gt;only&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Assume&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;payments&lt;/span&gt; &lt;span class="nx"&gt;endpoint&lt;/span&gt; &lt;span class="nx"&gt;accepts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Session 3 (tests):&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="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;writing&lt;/span&gt; &lt;span class="nx"&gt;integration&lt;/span&gt; &lt;span class="nx"&gt;tests&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;payments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;only&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Mock&lt;/span&gt; &lt;span class="nx"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Test&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;failure&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three run simultaneously. I merge the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;p&gt;The key insight is &lt;strong&gt;scope isolation&lt;/strong&gt;. Each subagent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has a single file or directory in scope&lt;/li&gt;
&lt;li&gt;Doesn't need to know what other agents are doing&lt;/li&gt;
&lt;li&gt;Can run completely in parallel&lt;/li&gt;
&lt;li&gt;Produces clean, mergeable output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When tasks are truly independent (different files, different concerns), parallelization has zero downsides and cuts wall-clock time by 3x.&lt;/p&gt;

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

&lt;p&gt;Here's my exact process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Before spawning subagents, I write a contract:

SHARED INTERFACE:
- POST /api/payments — accepts { amount: number, currency: string, token: string }
- Returns { success: boolean, subscriptionId?: string, error?: string }

Subagent A: implement this endpoint
Subagent B: call this endpoint from the UI
Subagent C: test this endpoint with mocks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interface definition is the only coordination needed. Once that's written, all three agents work independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where subagents break down
&lt;/h2&gt;

&lt;p&gt;Not everything parallelizes well:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sequential dependencies:&lt;/strong&gt; If Agent B needs Agent A's output to exist first, you can't parallelize. Classic example: schema migrations must run before the ORM code that uses them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared state:&lt;/strong&gt; If two agents both modify &lt;code&gt;config.js&lt;/code&gt;, you'll get merge conflicts. Keep scopes strictly separate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discovery tasks:&lt;/strong&gt; When you don't know what you want yet, a single exploratory session is better than multiple parallel ones.&lt;/p&gt;

&lt;p&gt;Rule of thumb: if you can write the interface contract before starting, you can parallelize. If you're still discovering the interface, go single-threaded first.&lt;/p&gt;

&lt;h2&gt;
  
  
  My actual workflow in 2026
&lt;/h2&gt;

&lt;p&gt;I use the SimplyLouie API (&lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;$10/month developer tier&lt;/a&gt;) for all my subagent sessions. It gives me direct API access with higher rate limits — critical when running 3-4 sessions simultaneously.&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;# Each subagent is just a curl call with a system prompt&lt;/span&gt;
curl https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "claude-sonnet",
    "system": "You are handling backend only. Scope: src/routes/payments.js",
    "messages": [{"role": "user", "content": "Implement Stripe webhook handler"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have a small shell script that spawns 3 of these in parallel and collects the outputs:&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;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# spawn_agents.sh&lt;/span&gt;

agent&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;
  curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://simplylouie.com/api/chat &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$system&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$task&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}]}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"/tmp/agent_&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Spawn in parallel&lt;/span&gt;
agent &lt;span class="s2"&gt;"backend"&lt;/span&gt; &lt;span class="s2"&gt;"Handle backend only. Scope: src/routes/"&lt;/span&gt; &lt;span class="s2"&gt;"Implement payment route"&lt;/span&gt; &amp;amp;
agent &lt;span class="s2"&gt;"frontend"&lt;/span&gt; &lt;span class="s2"&gt;"Handle frontend only. Scope: src/components/"&lt;/span&gt; &lt;span class="s2"&gt;"Build payment form"&lt;/span&gt; &amp;amp;
agent &lt;span class="s2"&gt;"tests"&lt;/span&gt; &lt;span class="s2"&gt;"Write tests only. Scope: tests/"&lt;/span&gt; &lt;span class="s2"&gt;"Test payment flow"&lt;/span&gt; &amp;amp;

&lt;span class="nb"&gt;wait
echo&lt;/span&gt; &lt;span class="s2"&gt;"All agents complete"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/agent_&lt;span class="k"&gt;*&lt;/span&gt;.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results after 3 months
&lt;/h2&gt;

&lt;p&gt;I've shipped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A full authentication system (backend + frontend + tests) in one session&lt;/li&gt;
&lt;li&gt;A data export feature (CSV + JSON + API endpoint) in parallel&lt;/li&gt;
&lt;li&gt;A notification system (email + push + in-app) simultaneously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical time savings: &lt;strong&gt;40-60% faster&lt;/strong&gt; on features that decompose cleanly.&lt;/p&gt;

&lt;p&gt;The biggest unlock wasn't the speed — it was that I stopped context-switching. Each agent is laser-focused on one thing. The quality went up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start simple
&lt;/h2&gt;

&lt;p&gt;You don't need complex orchestration to start. Just:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the interface contract first&lt;/li&gt;
&lt;li&gt;Assign one file per agent&lt;/li&gt;
&lt;li&gt;Run them in parallel (multiple browser tabs, multiple API calls, whatever)&lt;/li&gt;
&lt;li&gt;Merge the outputs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No frameworks needed. The parallelization is in your hands, not in the model.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I run all my subagent sessions through &lt;a href="https://simplylouie.com/developers" rel="noopener noreferrer"&gt;SimplyLouie's developer API&lt;/a&gt; — $10/month flat rate, no per-token billing surprises. Worth it if you're running multiple concurrent sessions.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>claudecode</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
