<?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: Mikael A</title>
    <description>The latest articles on DEV Community by Mikael A (@mikaelaldy).</description>
    <link>https://dev.to/mikaelaldy</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%2F1126907%2Fa3fdd359-49e3-4b49-8755-ddf762652cef.png</url>
      <title>DEV Community: Mikael A</title>
      <link>https://dev.to/mikaelaldy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mikaelaldy"/>
    <language>en</language>
    <item>
      <title>StudioShot AI</title>
      <dc:creator>Mikael A</dc:creator>
      <pubDate>Mon, 10 Nov 2025 23:59:29 +0000</pubDate>
      <link>https://dev.to/mikaelaldy/studioshot-ai-4kj</link>
      <guid>https://dev.to/mikaelaldy/studioshot-ai-4kj</guid>
      <description>&lt;h1&gt;
  
  
  Building StudioShot AI: Transforming Product Photography with Gemini and Cloud Run
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The $2000 Problem
&lt;/h2&gt;

&lt;p&gt;Imagine you're a small business owner who just launched a handcrafted jewelry line. You've spent months perfecting your products, but when it comes time to sell online, you face a harsh reality: your iPhone photos look amateurish next to competitors with professional studio shots. &lt;/p&gt;

&lt;p&gt;The quote from a professional photographer? &lt;strong&gt;$2,000 for a single product shoot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the problem I set out to solve with &lt;strong&gt;StudioShot AI&lt;/strong&gt; - an AI-powered platform that transforms basic product photos into professional studio-quality images in seconds, not days.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclosure&lt;/strong&gt;: I created this blog post for the purposes of entering the Cloud Run Hackathon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Birth of an Idea
&lt;/h2&gt;

&lt;p&gt;As someone who has worked with small businesses, I've seen this pattern repeatedly: great products held back by poor visual presentation. The options were limited - either pay thousands for professional photography or settle for mediocre images that hurt conversion rates.&lt;/p&gt;

&lt;p&gt;But what if AI could bridge this gap? With Google's new Gemini models and their impressive multi-modal capabilities, I realized this was finally possible. And thus, StudioShot AI was born.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://studioshot-ai-760988867361.us-west1.run.app/" rel="noopener noreferrer"&gt;https://studioshot-ai-760988867361.us-west1.run.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbze6myzmd11xrkomutg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbze6myzmd11xrkomutg.png" alt="landing page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack: Why These Choices Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend: React 19 + TypeScript + Vite
&lt;/h3&gt;

&lt;p&gt;I chose &lt;strong&gt;React 19&lt;/strong&gt; for its concurrent features and improved performance. Combined with &lt;strong&gt;TypeScript&lt;/strong&gt; for type safety and &lt;strong&gt;Vite&lt;/strong&gt; for lightning-fast development, I could iterate quickly while maintaining code quality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Type-safe state management for complex workflows&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GalleryItem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;edited&lt;/span&gt;&lt;span class="dl"&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;generated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;originalSrc&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&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;
  
  
  The AI Powerhouse: Three Gemini Models
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting. Instead of using a single AI model, I leveraged &lt;strong&gt;three different Google AI models&lt;/strong&gt;, each optimized for specific tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 2.5 Pro&lt;/strong&gt; - Image analysis and prompt generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 2.5 Flash Image&lt;/strong&gt; - Fast image-to-image editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imagen 4.0&lt;/strong&gt; - High-quality text-to-image generation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why three models? Because specialized tools beat generalists every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: How It All Fits Together
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhr85y0s1rx6z57wzv66z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhr85y0s1rx6z57wzv66z.png" alt="diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flow is elegant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Upload → Gemini 2.5 Pro (Analysis) → AI Suggestions
     ↓
User Selects Prompt → Gemini Flash Image (Transform) → Result
     ↓
Save to Gallery (LocalStorage) → Download/Share
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For generation from scratch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Prompt → Imagen 4.0 (Generate) → Result
     ↓
Refine → Gemini Flash Image (Edit) → Improved Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Code: Where Magic Happens
&lt;/h2&gt;

&lt;p&gt;Let me walk you through the key implementation details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Image Analysis with Gemini 2.5 Pro
&lt;/h3&gt;

&lt;p&gt;When a user uploads an image, I need to understand what's in it and suggest relevant transformations. Gemini 2.5 Pro excels at this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;analyzeImage&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;imageDataUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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;base64Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mimeType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dataUrlToBlobParts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageDataUrl&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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&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;gemini-2.5-pro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;parts&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="na"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64Data&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="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="s2"&gt;`Analyze this product photo. Suggest 4 detailed, distinct 
                 prompts to transform it into a professional studio-quality 
                 image. Focus on specific styles like 'minimalist', 
                 'cinematic', 'e-commerce white background', and 
                 'dramatic lighting'.`&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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responseMimeType&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;responseSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARRAY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A detailed prompt for image transformation.&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="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&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;parse&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;text&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The beauty here is the &lt;strong&gt;structured JSON output&lt;/strong&gt;. Instead of parsing free text, Gemini returns a clean array of suggestions I can immediately use in the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Image Transformation with Gemini 2.5 Flash Image
&lt;/h3&gt;

&lt;p&gt;Once the user selects (or customizes) a prompt, the transformation happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editImage&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;imageDataUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;base64Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mimeType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dataUrlToBlobParts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageDataUrl&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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&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;gemini-2.5-flash-image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;parts&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="na"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mimeType&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="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;prompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responseModalities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Modality&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IMAGE&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Extract the generated image&lt;/span&gt;
  &lt;span class="k"&gt;for &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;part&lt;/span&gt; &lt;span class="k"&gt;of&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;candidates&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;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parts&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="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inlineData&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;editedBase64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inlineData&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editedMimeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`data:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;editedMimeType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;base64,&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;editedBase64&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="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No image was generated by the model.&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;p&gt;&lt;strong&gt;Gemini 2.5 Flash Image&lt;/strong&gt; is blazingly fast - typically returning results in 2-5 seconds. This speed is crucial for the iterative refinement feature, where users might make 5-10 adjustments before getting the perfect result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text-to-Image with Imagen 4.0
&lt;/h3&gt;

&lt;p&gt;For the "Generate from Scratch" feature, I used Imagen 4.0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateImage&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;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateImages&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;imagen-4.0-generate-001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;numberOfImages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;outputMimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1:1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &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;generatedImages&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;generatedImages&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;0&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;base64ImageBytes&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;generatedImages&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;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageBytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`data:image/png;base64,&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;base64ImageBytes&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No image was generated.&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;p&gt;Imagen 4.0 produces photorealistic results that often rival professional photography.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixd9xbczkd2ege4oquzg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixd9xbczkd2ege4oquzg.jpeg" alt="photorealistic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying to Cloud Run: The Journey
&lt;/h2&gt;

&lt;p&gt;This is where Cloud Run truly shines. Here's why I chose it and how the deployment went.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Cloud Run?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Serverless Simplicity&lt;/strong&gt;: No infrastructure management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Scaling&lt;/strong&gt;: Handles traffic spikes without configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Effective&lt;/strong&gt;: Pay only for what you use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container-Based&lt;/strong&gt;: Full control over the runtime environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in HTTPS&lt;/strong&gt;: Secure by default with automatic SSL certificates&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Deployment Process
&lt;/h3&gt;

&lt;p&gt;First, I containerized the Vite app. Here's my Dockerfile:&lt;br&gt;
&lt;/p&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="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:18-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&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="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; nginx.conf /etc/nginx/conf.d/default.conf&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["nginx", "-g", "daemon off;"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then deployed to Cloud Run:&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;# Build the container&lt;/span&gt;
gcloud builds submit &lt;span class="nt"&gt;--tag&lt;/span&gt; gcr.io/[PROJECT-ID]/studioshot-ai

&lt;span class="c"&gt;# Deploy to Cloud Run&lt;/span&gt;
gcloud run deploy studioshot-ai &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt; gcr.io/[PROJECT-ID]/studioshot-ai &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--platform&lt;/span&gt; managed &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-west1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allow-unauthenticated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Deployed in under 5 minutes! 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud Run Benefits I Experienced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Instant Scaling&lt;/strong&gt;: During testing with multiple users, Cloud Run automatically spun up additional instances without any configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Global Performance&lt;/strong&gt;: The CDN integration meant fast load times worldwide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Zero Downtime Deployments&lt;/strong&gt;: I could push updates without taking the app offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cost Efficiency&lt;/strong&gt;: For a hackathon project with variable traffic, Cloud Run's pay-per-use model is perfect. When no one's using the app, costs approach zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges Faced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Environment Variables&lt;/strong&gt;: Initially struggled with exposing the Gemini API key to the browser. Solution: Used Vite's &lt;code&gt;import.meta.env&lt;/code&gt; pattern and built the key into the bundle (with rate limiting on the API side).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cold Starts&lt;/strong&gt;: First noticed a 2-3 second delay on the first request after idle. Implemented a "keep-warm" strategy for the production version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CORS Issues&lt;/strong&gt;: Needed to configure proper CORS headers for API calls. Cloud Run's ingress settings made this straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features in Action
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Transform Mode: AI-Powered Editing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkjr9vs3v7ybrvs4xk36.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkjr9vs3v7ybrvs4xk36.jpeg" alt="Transform Mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workflow is intuitive:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Drag and drop product photo&lt;/li&gt;
&lt;li&gt;AI analyzes and suggests 4 transformation styles&lt;/li&gt;
&lt;li&gt;Select or customize prompt&lt;/li&gt;
&lt;li&gt;Get professional result in seconds&lt;/li&gt;
&lt;li&gt;Refine iteratively if needed&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Generate Mode: Create from Imagination
&lt;/h3&gt;

&lt;p&gt;![Generate Mode Interface][PLACEHOLDER: Insert generate mode screenshot]&lt;/p&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualizing products before manufacturing&lt;/li&gt;
&lt;li&gt;Creating marketing mockups&lt;/li&gt;
&lt;li&gt;Rapid prototyping of product photography ideas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Before/After Comparison
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;react-compare-image&lt;/code&gt;, users can slide between original and transformed images - a powerful way to showcase the AI's capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prompt Engineering is an Art
&lt;/h3&gt;

&lt;p&gt;Early iterations produced inconsistent results. I learned that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specificity matters&lt;/strong&gt;: "minimalist white background" beats "nice background"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style keywords work&lt;/strong&gt;: Terms like "cinematic," "dramatic," "e-commerce" guide the AI effectively&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context helps&lt;/strong&gt;: Including product type in prompts improves accuracy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multi-Modal AI is Powerful
&lt;/h3&gt;

&lt;p&gt;The combination of vision + language understanding in Gemini 2.5 Pro creates a seamless experience. Users don't need to know how to write good prompts - the AI does it for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Management Complexity
&lt;/h3&gt;

&lt;p&gt;With three different workflows (Transform, Generate, Refine), managing React state became complex. I used separate state trees and careful use of &lt;code&gt;useCallback&lt;/code&gt; to prevent unnecessary re-renders.&lt;/p&gt;

&lt;h3&gt;
  
  
  LocalStorage is Underrated
&lt;/h3&gt;

&lt;p&gt;For this use case, I didn't need a backend database. Browser LocalStorage handles gallery persistence perfectly, keeping the architecture simple and costs low.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Performance Metrics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average transformation time&lt;/strong&gt;: 3-5 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average generation time&lt;/strong&gt;: 5-8 seconds
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success rate&lt;/strong&gt;: 95% of prompts produce usable results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold start time&lt;/strong&gt;: ~2 seconds on Cloud Run&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Business Impact Potential
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost savings&lt;/strong&gt;: $1,500-2,000 per product line vs. professional photography&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: Hours → Seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iteration&lt;/strong&gt;: Unlimited refinements vs. expensive reshoots&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;🚀 Live App&lt;/strong&gt;: &lt;a href="https://studioshot-ai-760988867361.us-west1.run.app/" rel="noopener noreferrer"&gt;https://studioshot-ai-760988867361.us-west1.run.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💻 GitHub&lt;/strong&gt;: &lt;a href="https://github.com/mikaelaldy/StudioShot-AI" rel="noopener noreferrer"&gt;https://github.com/mikaelaldy/StudioShot-AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎨 AI Studio&lt;/strong&gt;: &lt;a href="https://ai.studio/apps/drive/1jw_DxphHEMww-aoOwhXFpb4LO78p5Uxq" rel="noopener noreferrer"&gt;View my prompts&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;I have ambitious plans for StudioShot AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch processing&lt;/strong&gt; for multiple products&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style templates&lt;/strong&gt; for different industries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background library&lt;/strong&gt; with curated professional backgrounds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce integrations&lt;/strong&gt; (Shopify, WooCommerce)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team collaboration&lt;/strong&gt; features&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building StudioShot AI for the Cloud Run Hackathon taught me that the barrier between "professional" and "amateur" is rapidly dissolving thanks to AI. What once required thousands of dollars and professional equipment can now be achieved with a few clicks.&lt;/p&gt;

&lt;p&gt;But more importantly, it showed me the power of &lt;strong&gt;combining specialized AI models&lt;/strong&gt; rather than relying on a single generalist. Gemini 2.5 Pro for analysis, Flash Image for speed, and Imagen for quality - each playing to its strengths.&lt;/p&gt;

&lt;p&gt;Cloud Run made deployment almost trivially easy, letting me focus on building features instead of managing infrastructure. For anyone building AI applications, this combination of Gemini + Cloud Run is incredibly powerful.&lt;/p&gt;

&lt;p&gt;The $2,000 problem? &lt;strong&gt;Solved.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to build something similar?&lt;/strong&gt; The code is open source. Star the repo, fork it, and let me know what you build!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Participating in the Cloud Run Hackathon?&lt;/strong&gt; Share your projects with #CloudRunHackathon - I'd love to see what you're building!&lt;/p&gt;

</description>
      <category>cloudrunhackathon</category>
    </item>
    <item>
      <title>Can’t Start That Big Project? This App Helps ADHD Brains Beat Task Paralysis.</title>
      <dc:creator>Mikael A</dc:creator>
      <pubDate>Mon, 15 Sep 2025 18:36:28 +0000</pubDate>
      <link>https://dev.to/mikaelaldy/cant-start-that-big-project-this-app-helps-adhd-brains-beat-task-paralysis-1fdb</link>
      <guid>https://dev.to/mikaelaldy/cant-start-that-big-project-this-app-helps-adhd-brains-beat-task-paralysis-1fdb</guid>
      <description>&lt;p&gt;Ever stared at a huge task (like writing a report or cleaning the garage) and felt completely frozen? You know you need to start, but your brain just says "nope." This overwhelming feeling is called task paralysis, and it's a daily struggle for many people with ADHD.&lt;/p&gt;

&lt;p&gt;That’s why I built Firefly, a smart focus app designed to break down that "wall of awful" and help you start meaningful work in under a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Firefly Turns "I Can't" into "I Just Did"
&lt;/h2&gt;

&lt;p&gt;Firefly isn't just another timer or to-do list. It was built from the ground up with the ADHD brain in mind. The entire process is designed to be simple, visual, and incredibly fast, capturing your motivation the moment it strikes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Just Tell Firefly Your Goal
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fig1v22hjufr77tfqjwk9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fig1v22hjufr77tfqjwk9.jpeg" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;br&gt;
There are no complicated forms. You start with a single, simple question: "What do you want to finish?" Just type your goal in plain language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Get an Instant, Actionable Plan
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flemjxa57vhnjekc9pviq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flemjxa57vhnjekc9pviq.jpeg" alt=" " width="800" height="905"&gt;&lt;/a&gt;&lt;br&gt;
The moment you enter your goal, Firefly’s AI gets to work. It instantly gives you a tiny, 60-second first step to get you started. This isn't a vague suggestion; it's a concrete micro-task designed to be so easy you can't say no.&lt;/p&gt;

&lt;p&gt;Alongside that first step, you get a full, editable action plan with time estimates for each task, giving you a clear roadmap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Pick an Action and Start the Timer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymmsd0c2r5alwrgjk42l.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymmsd0c2r5alwrgjk42l.jpeg" alt=" " width="800" height="577"&gt;&lt;/a&gt;&lt;br&gt;
You are in complete control. You can use the standard timer presets or, even better, select one of the AI's time estimates for a specific action. This helps you commit to a single task for a realistic amount of time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Stay Focused with a Visual Timer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxwo19way5spsnpd0gel.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxwo19way5spsnpd0gel.jpeg" alt=" " width="800" height="1045"&gt;&lt;/a&gt;&lt;br&gt;
One of the biggest challenges for people with ADHD is "time blindness": the inability to sense the passage of time. Firefly’s large, visual timer makes time tangible. The clean, distraction-free interface shows you only the current action, helping you stay locked in.&lt;/p&gt;

&lt;p&gt;Built for a Neurodivergent World&lt;br&gt;
Firefly is more than a tool; it's a companion for anyone whose brain works a little differently. It offers gentle accountability without judgment and celebrates every minute of focus, not just "perfect" sessions.&lt;/p&gt;

&lt;p&gt;If you’ve ever felt stuck, give Firefly a try. Your next productive session is just a few seconds away.&lt;/p&gt;

&lt;p&gt;Try Firefly: &lt;a href="https://firefly-beta.vercel.app/" rel="noopener noreferrer"&gt;Firefly&lt;/a&gt;&lt;br&gt;
Check out the code: &lt;a href="https://github.com/mikaelaldy/firefly" rel="noopener noreferrer"&gt;firefly&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kiro</category>
    </item>
  </channel>
</rss>
