<?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>Forem: Grace Yuen</title>
    <description>The latest articles on Forem by Grace Yuen (@gracetyy).</description>
    <link>https://forem.com/gracetyy</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%2F3036295%2F8ccbf487-f9ae-419f-881f-a8ffc714fadf.png</url>
      <title>Forem: Grace Yuen</title>
      <link>https://forem.com/gracetyy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gracetyy"/>
    <language>en</language>
    <item>
      <title>I Built a 3D Gesture-Controlled Instagram Christmas Tree in a Day 🎄</title>
      <dc:creator>Grace Yuen</dc:creator>
      <pubDate>Thu, 25 Dec 2025 07:07:30 +0000</pubDate>
      <link>https://forem.com/gracetyy/i-built-a-3d-gesture-controlled-instagram-christmas-tree-in-a-day-3d3</link>
      <guid>https://forem.com/gracetyy/i-built-a-3d-gesture-controlled-instagram-christmas-tree-in-a-day-3d3</guid>
      <description>&lt;p&gt;This Christmas, a friend and I decided to see how far we could push a small idea in just one day: What if a Christmas tree could grow out of your Instagram memories and react to your hand gestures?&lt;/p&gt;

&lt;p&gt;The result is a 3D Christmas tree where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each ornament is one of your latest Instagram photos.&lt;/li&gt;
&lt;li&gt;You can explore the tree using hand gestures in front of your camera.&lt;/li&gt;
&lt;li&gt;Everything runs in the browser, so you can share it easily with friends and family.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Live demo: &lt;a href="https://www.christmas-tree.fun/" rel="noopener noreferrer"&gt;https://www.christmas-tree.fun/&lt;/a&gt; &lt;br&gt;
⭐ GitHub Repo: &lt;a href="https://github.com/gracetyy/christmas-tree/" rel="noopener noreferrer"&gt;https://github.com/gracetyy/christmas-tree/&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%2Fmedia.daily.dev%2Fimage%2Fupload%2Fs--b_aYPTVa--%2Ff_auto%2Fv1766645961%2Fugc%2Fcontent_68e08cec-6f3a-47e2-b475-81ca11576e00%3F_a%3DBAMAK%2BZW0" 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%2Fmedia.daily.dev%2Fimage%2Fupload%2Fs--b_aYPTVa--%2Ff_auto%2Fv1766645961%2Fugc%2Fcontent_68e08cec-6f3a-47e2-b475-81ca11576e00%3F_a%3DBAMAK%2BZW0" alt="Screenshot 2025-12-25 145911"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Core Ideas
&lt;/h2&gt;

&lt;p&gt;The project was built around three main goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a playful, seasonal experience that feels magical but is still technically solid.&lt;/li&gt;
&lt;li&gt;Use off-the-shelf tools so other developers can easily fork and extend it.
&lt;/li&gt;
&lt;li&gt;Treat it as a quick experiment in combining &lt;strong&gt;3D graphics&lt;/strong&gt;, &lt;strong&gt;real-time interaction&lt;/strong&gt;, and &lt;strong&gt;social media content&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Tech Stack Overview
&lt;/h2&gt;

&lt;p&gt;At a high level, the project combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;3D scene&lt;/strong&gt; for the tree, presents and background by Three.js&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;gesture input layer&lt;/strong&gt; that maps hand movement to camera controls (similar to MediaPipe Hands)
&lt;/li&gt;
&lt;li&gt;A backend workflow to fetch the latest photos from a given Instagram username powered by &lt;a href="https://bubblelab.ai/" rel="noopener noreferrer"&gt;Bubble Lab&lt;/a&gt;, an open-source TypeScript-native workflow automation platform where you can prompt and get both a visual flow and real TypeScript code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to check the repo for the exact implementation details and see how the pieces fit together in code.&lt;/p&gt;


&lt;h2&gt;
  
  
  Things Learned / Interesting Challenges
&lt;/h2&gt;

&lt;p&gt;Working on this in such a short time frame surfaced a few interesting areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UX for gesture vs mouse&lt;/strong&gt;: Making sure the tree still feels usable with traditional input while keeping gestures fun and not frustrating.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance on mobile&lt;/strong&gt;: Balancing visual detail of the tree with smooth interaction on phones.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camera mapping from gestures&lt;/strong&gt;: Designing a mapping from 2D hand position to orbit-camera azimuth/elevation that feels intuitive, doesn’t cause motion sickness, and still lets users reach all sides of the tree.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Open to feedback or PRs and wish everyone have a wonderful christmas!!&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gracetyy" rel="noopener noreferrer"&gt;
        gracetyy
      &lt;/a&gt; / &lt;a href="https://github.com/gracetyy/christmas-tree" rel="noopener noreferrer"&gt;
        christmas-tree
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Merry Christmas! Decorate your own 3D Christmas Tree with Instagram photos
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🎄 Make your own 3D Christmas Tree with your photos!&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Transform your favorite memories into a magical, interactive 3D holiday experience! This project lets you create a beautiful, personalized Christmas tree decorated with your own photos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✨ Try it out live at: &lt;a href="https://www.christmas-tree.fun/" rel="nofollow noopener noreferrer"&gt;https://www.christmas-tree.fun/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎥 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/gracetyy/christmas-tree/./Duo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgracetyy%2Fchristmas-tree%2F.%2FDuo.gif" alt="Demo 1 — scripting @duolingo Instagram as an example" width="360"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/gracetyy/christmas-tree/./Duo2.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgracetyy%2Fchristmas-tree%2F.%2FDuo2.gif" alt="Demo 2 — scripting @duolingo Instagram as an example" width="360"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Demo: scripting &lt;code&gt;@duolingo&lt;/code&gt; Instagram as an example input for the Instagram import.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📸 Your Photos, Your Tree&lt;/strong&gt;: Upload photos from your device or instantly import them from any &lt;strong&gt;Instagram&lt;/strong&gt; profile!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🖐️ Magic Hand Controls&lt;/strong&gt;: Control the camera with hand gestures in front of your webcam.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🎬 Cinematic Videos&lt;/strong&gt;: Record high-quality videos of your tree (360° rotation or cinematic tour).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🖼️ Instant Postcards&lt;/strong&gt;: Download a high-definition snapshot of your tree with a custom "Merry Christmas" greeting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;👤 Personalized Greeting&lt;/strong&gt;: Enter your name to see a custom "Merry Christmas [Your Name]!" message.&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🖐️ Hand Mode Tutorial&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Switch to &lt;strong&gt;Hand Mode&lt;/strong&gt;…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gracetyy/christmas-tree" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





</description>
      <category>webdev</category>
      <category>programming</category>
      <category>sideprojects</category>
      <category>threejs</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Grace Yuen</dc:creator>
      <pubDate>Mon, 10 Nov 2025 17:54:30 +0000</pubDate>
      <link>https://forem.com/gracetyy/-39f9</link>
      <guid>https://forem.com/gracetyy/-39f9</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/gracetyy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F3036295%2F8ccbf487-f9ae-419f-881f-a8ffc714fadf.png" alt="gracetyy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/gracetyy/craftscapehk-building-an-ai-ar-platform-for-cultural-heritage-on-google-cloud-run-1kfp" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;CraftscapeHK: Building an AI + AR Platform for Cultural Heritage on Google Cloud Run&lt;/h2&gt;
      &lt;h3&gt;Grace Yuen ・ Nov 10&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#gcp&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cloudrunhackathon&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>ai</category>
      <category>webdev</category>
      <category>gcp</category>
      <category>cloudrunhackathon</category>
    </item>
    <item>
      <title>CraftscapeHK: Building an AI + AR Platform for Cultural Heritage on Google Cloud Run</title>
      <dc:creator>Grace Yuen</dc:creator>
      <pubDate>Mon, 10 Nov 2025 17:32:36 +0000</pubDate>
      <link>https://forem.com/gracetyy/craftscapehk-building-an-ai-ar-platform-for-cultural-heritage-on-google-cloud-run-1kfp</link>
      <guid>https://forem.com/gracetyy/craftscapehk-building-an-ai-ar-platform-for-cultural-heritage-on-google-cloud-run-1kfp</guid>
      <description>&lt;p&gt;&lt;a href="https://craftscape-frontend-998275462099.us-central1.run.app" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try Our App&lt;/a&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm writing this blog as a participant in Cloud Run Hackathon by Google Cloud&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Throughout this month, we have built our project, CraftscapeHK, for the &lt;a href="https://run.devpost.com/" rel="noopener noreferrer"&gt;Google Cloud Run Hackathon&lt;/a&gt;. Here's how we leveraged Cloud Run to create a scalable, cost-effective solution for preserving Hong Kong's endangered traditional crafts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hong Kong's traditional crafts—hand-carved mahjong tiles, painted porcelain, cheonsgam, and neon signs—are disappearing. More than &lt;strong&gt;70% of craft shops&lt;/strong&gt; have closed in recent years, typical revenues have &lt;strong&gt;fallen 30–50%&lt;/strong&gt;, and &lt;strong&gt;80% of artisans&lt;/strong&gt; say their children won't continue the trade. The solution isn't nostalgic preservation—it's economic viability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CraftscapeHK&lt;/strong&gt; (藝守) is an AI + AR e-commerce platform that bridges cultural heritage with modern technology. We built it on &lt;strong&gt;Google Cloud Run&lt;/strong&gt;, and in this post, I'll share how we leveraged Cloud Run's serverless architecture to create a scalable, cost-effective solution for preserving endangered crafts while connecting artisans with global audiences.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is CraftscapeHK?
&lt;/h2&gt;

&lt;p&gt;Users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explore craft stories&lt;/strong&gt; through an engaging Tinder-like interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design custom pieces&lt;/strong&gt; using our AI Creation Studio and commission artisans directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experience AR exhibitions&lt;/strong&gt; with 360° product views and immersive storytelling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover local events&lt;/strong&gt; through a cultural events calendar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support artisans&lt;/strong&gt; by purchasing products and attending workshops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform integrates &lt;strong&gt;Google Gemini API&lt;/strong&gt; for AI-powered design generation and uses &lt;strong&gt;AR&lt;/strong&gt; for immersive 3D experiences.&lt;/p&gt;




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

&lt;p&gt;We chose &lt;strong&gt;Cloud Run&lt;/strong&gt; for three key reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Containerization-Native&lt;/strong&gt;: Ship code in containers; Cloud Run handles the rest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-Effective&lt;/strong&gt;: Pay only for actual request processing, perfect for unpredictable hackathon traffic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal Ops Overhead&lt;/strong&gt;: No Kubernetes clusters to manage, no node pools to configure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our architecture consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend Service&lt;/strong&gt;: React 19 + Vite, served via Nginx on Cloud Run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend Service&lt;/strong&gt;: NestJS + SQLite, running on Cloud Run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container Registry (GCR)&lt;/strong&gt;: Image storage and versioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Build&lt;/strong&gt;: Automated CI/CD pipeline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Scheduler&lt;/strong&gt;: Scheduled maintenance tasks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&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%2Fyv47qhqux4okxoxjyo69.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%2Fyv47qhqux4okxoxjyo69.png" alt="Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Container Design &amp;amp; Optimization
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Frontend Container
&lt;/h4&gt;

&lt;p&gt;We built the frontend using a &lt;strong&gt;multi-stage Docker build&lt;/strong&gt; approach. The builder stage compiles our React 19 + TypeScript code with Vite, while the production stage uses Nginx Alpine to serve the compiled assets. This drastically reduces the final image size to just &lt;strong&gt;~15MB&lt;/strong&gt; compared to ~400MB if we included the builder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key optimizations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-stage builds&lt;/strong&gt; reduce final image size and attack surface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alpine Linux&lt;/strong&gt; base image minimizes container overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; as reverse proxy handles static assets efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resource allocation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: 256Mi (sufficient for serving static assets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: 1 vCPU (adequate for request handling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeout&lt;/strong&gt;: 60 seconds (reasonable for frontend logic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max instances&lt;/strong&gt;: 10 (prevents runaway scaling costs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Backend Container
&lt;/h4&gt;

&lt;p&gt;The backend uses a single-stage Docker build because we need TypeScript compilation and canvas dependencies at runtime for flexibility. This results in a ~250MB image, which is still lean for Cloud Run's container standards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why single-stage?&lt;/strong&gt; We need build tools available in the production image for runtime operations and ensuring all dependencies are present.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource allocation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: 512Mi (handles NestJS runtime + database operations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: 1 vCPU (sufficient for API processing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeout&lt;/strong&gt;: 300 seconds (allows longer-running AI generation requests)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max instances&lt;/strong&gt;: 10 (prevents cascading failures)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Automatic Scaling
&lt;/h3&gt;

&lt;p&gt;Cloud Run's built-in autoscaling is powerful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request arrives → Cold start (scale-to-zero)
   ↓
Container boots (2-3 seconds for backend, 1-2 for frontend)
   ↓
Request processes
   ↓
No traffic for 15 minutes → Scales down to 0 (no cost!)
   ↓
Next request triggers cold start again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why this matters for hackathons&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No cost during idle time&lt;/strong&gt;: Perfect for projects with sporadic traffic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic horizontal scaling&lt;/strong&gt;: 5 concurrent requests? Spin up 5 instances automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictable billing&lt;/strong&gt;: Only pay for CPU/memory while handling requests&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. CI/CD Pipeline with Cloud Build
&lt;/h3&gt;

&lt;p&gt;Cloud Build orchestrates our entire deployment pipeline automatically on each GitHub push. The pipeline has several key steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build Phase&lt;/strong&gt;: Frontend and backend Docker images are built in parallel, tagged with both the commit SHA and &lt;code&gt;latest&lt;/code&gt; tag for easy rollbacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push Phase&lt;/strong&gt;: Both images are pushed to Google Container Registry (GCR) with commit SHA tags and updated &lt;code&gt;latest&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy Phase&lt;/strong&gt;: The backend service is deployed to Cloud Run first with environment variables like &lt;code&gt;GEMINI_API_KEY&lt;/code&gt; injected at runtime, followed by the frontend deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialization Phase&lt;/strong&gt;: The pipeline waits for the backend service to be healthy, then seeds the SQLite database via an admin endpoint to ensure initial data is loaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated on push&lt;/strong&gt;: Every GitHub commit triggers a complete build and deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit SHA tagging&lt;/strong&gt;: Easy rollbacks—just deploy a previous image version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel builds&lt;/strong&gt;: Frontend and backend build simultaneously for speed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt;: Database seeding only happens after backend is confirmed ready&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. Networking &amp;amp; Routing
&lt;/h3&gt;

&lt;p&gt;Nginx acts as a reverse proxy on the frontend, routing requests intelligently between static content and backend APIs. Static assets like HTML, CSS, and JavaScript files are served directly from Nginx with minimal latency, while API requests are proxied to the backend Cloud Run service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This design&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serves static assets (React bundle) directly from Nginx with near-zero latency&lt;/li&gt;
&lt;li&gt;Routes API calls to the backend service transparently&lt;/li&gt;
&lt;li&gt;Reduces backend load and improves perceived application performance&lt;/li&gt;
&lt;li&gt;Enables caching strategies at the proxy level&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  5. Database Strategy: SQLite in Container
&lt;/h3&gt;

&lt;p&gt;We bundled SQLite directly in the backend container, seeding the database on deployment with craft data and artisan information. The database file persists within the container instance, surviving restarts within that instance's lifetime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why SQLite on Cloud Run?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No external database dependency&lt;/strong&gt;: Simpler deployments with fewer failure points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data persistence&lt;/strong&gt;: The database survives within an instance and is restored across scale-ups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: Zero database infrastructure costs—no Cloud SQL instances to maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seeding on deploy&lt;/strong&gt;: An admin endpoint initializes the database automatically on first deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Not suitable for multi-instance concurrent writes (SQLite has write-locking)&lt;/li&gt;
&lt;li&gt;✅ Perfect for read-heavy, artisan-focused platforms&lt;/li&gt;
&lt;li&gt;✅ Great for hackathon MVPs and proof-of-concepts&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Data Flow: How Requests Travel Through Cloud Run
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
    ↓
[Frontend Cloud Run] (Nginx on port 8080)
    ├─ Static Assets (/index.html, /css/...) → Served directly from /usr/share/nginx/html
    └─ API Requests (/api/*) → Proxied to backend
         ↓
      [Backend Cloud Run] (NestJS on port 3000)
         ├─ API Processing
         ├─ SQLite Query
         └─ Gemini API Call (for AI image generation)
             ↓
             [Google Gemini API]
             ↓
    Response with generated image
             ↓
    JSON response
             ↓
    Frontend Renders UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Performance characteristics&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cold start (first request in 15+ minutes)&lt;/strong&gt;: 2-5 seconds total&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warm start (subsequent requests)&lt;/strong&gt;: &amp;lt;100ms API latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static asset serving&lt;/strong&gt;: &amp;lt;50ms (CDN-like caching via Nginx)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Cost Analysis: Why Cloud Run is Ideal for Hackathons
&lt;/h2&gt;

&lt;p&gt;Compared to alternatives, Cloud Run shines for hackathon projects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cost Factor&lt;/th&gt;
&lt;th&gt;Cloud Run&lt;/th&gt;
&lt;th&gt;App Engine&lt;/th&gt;
&lt;th&gt;Kubernetes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Idle time cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$10+/month&lt;/td&gt;
&lt;td&gt;$30+/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cold start&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2-5s&lt;/td&gt;
&lt;td&gt;3-8s&lt;/td&gt;
&lt;td&gt;10+s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Billing granularity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per 100ms&lt;/td&gt;
&lt;td&gt;Per instance/month&lt;/td&gt;
&lt;td&gt;Per node/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ops complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost for 100K req/month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$2&lt;/td&gt;
&lt;td&gt;~$15&lt;/td&gt;
&lt;td&gt;~$50+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Our actual estimate&lt;/strong&gt; (assuming 100K requests/month with 2s avg processing):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: ~$0.30/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: ~$2-4/month (depends on Gemini API calls)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total&lt;/strong&gt;: ~$3-5/month&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Key Features Leveraging Cloud Run
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. AI Image Generation
&lt;/h3&gt;

&lt;p&gt;The backend integrates with Google Gemini API to generate custom craft designs based on user prompts. Users describe their vision, and the AI generates unique personalized craft designs that can be commissioned from artisans.&lt;/p&gt;

&lt;p&gt;Cloud Run's 300-second timeout is crucial here, as AI model inference can take significant time. This generous timeout prevents requests from being cut off mid-processing, unlike traditional API Gateways with stricter limits.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Real-Time Artisan Messaging
&lt;/h3&gt;

&lt;p&gt;Users can message artisans directly through the platform for custom orders and inquiries. These messages are stored in SQLite and retrieved instantly, enabling seamless communication between craftspeople and customers.&lt;/p&gt;

&lt;p&gt;SQLite's reliability ensures messages aren't lost during container operations or scaling events.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. AR Asset Serving
&lt;/h3&gt;

&lt;p&gt;USDZ files (3D model format for augmented reality) are served as static assets from Nginx. These 3D craft models enable immersive AR experiences where users can visualize products in their own space before purchasing.&lt;/p&gt;

&lt;p&gt;Cloud Run's efficient static file serving means AR assets load quickly and reliably across different network conditions.&lt;/p&gt;


&lt;h2&gt;
  
  
  Deployment Command: From Zero to Live
&lt;/h2&gt;

&lt;p&gt;We simplified deployment to a single npm command that handles the entire process:&lt;/p&gt;

&lt;p&gt;Within 3-5 minutes, the deployment pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ Builds the frontend Docker image with Vite&lt;/li&gt;
&lt;li&gt;✅ Builds the backend Docker image with NestJS compiled&lt;/li&gt;
&lt;li&gt;✅ Pushes both images to Google Container Registry&lt;/li&gt;
&lt;li&gt;✅ Deploys backend to Cloud Run with environment variables&lt;/li&gt;
&lt;li&gt;✅ Deploys frontend to Cloud Run with backend URL configured&lt;/li&gt;
&lt;li&gt;✅ Seeds the SQLite database with craft and artisan data&lt;/li&gt;
&lt;li&gt;✅ Service is live and accessible globally&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Lessons Learned: Building on Cloud Run
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. &lt;strong&gt;Cold Starts Matter&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For user-facing services, 2-5 second cold starts are acceptable when the service starts from scratch after being idle. However, if cold starts become problematic, you can configure minimum instances to keep at least one warm. This trades off cost for guaranteed fast response times. We didn't use minimum instances to stay within tight hackathon budgets.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;strong&gt;SQLite Write Limitations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SQLite's write-locking mechanism isn't ideal for high-concurrency scenarios. For production systems with multiple writers, consider alternatives like Cloud SQL (PostgreSQL/MySQL), Firestore for real-time databases, or BigTable for large-scale analytics. For CraftscapeHK, our write volume is low (artisan edits, user orders), making SQLite a perfect fit.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. &lt;strong&gt;Secrets Management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Never hardcode API keys directly into containers. Instead, use Cloud Secret Manager or pass sensitive values as environment variables during deployment. This keeps secrets out of version control and audit logs, and enables easy rotation without rebuilding images.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. &lt;strong&gt;Monitoring is Critical&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Observability is key to understanding performance. Monitor request latency to identify cold start impact, track error rates to catch issues early, track memory usage to right-size resource allocation, and monitor billing to understand actual costs versus estimates. Cloud Logging provides comprehensive access to all service logs.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. &lt;strong&gt;Container Image Size&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Smaller images pull faster, resulting in quicker cold starts. Our frontend at 15MB starts in ~1-2 seconds, while our 250MB backend takes 3-5 seconds. Every 100MB of image size adds approximately 500ms to cold start time. Techniques like Alpine Linux base images, multi-stage builds, and minimal dependencies compound these savings.&lt;/p&gt;


&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;p&gt;If we were to scale CraftscapeHK beyond a hackathon project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Move to Cloud SQL&lt;/strong&gt; for reliable multi-instance database access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Cloud CDN&lt;/strong&gt; for global asset distribution (AR models, craft images)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Pub/Sub&lt;/strong&gt; for asynchronous AI processing (image generation can take 10+ seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cloud Tasks&lt;/strong&gt; for reliable artisan notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy to multiple regions&lt;/strong&gt; with Cloud Load Balancing for global latency&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cloud Run proves that you don't need Kubernetes expertise to run production workloads.&lt;/strong&gt; CraftscapeHK demonstrates how Cloud Run's serverless architecture enables small teams to:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Ship fast&lt;/strong&gt;: From code to deployed in minutes&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Scale automatically&lt;/strong&gt;: Handle traffic spikes without manual intervention&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Pay fairly&lt;/strong&gt;: Only for resources consumed, $0 during idle time&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Focus on product&lt;/strong&gt;: Not infrastructure&lt;/p&gt;

&lt;p&gt;For cultural heritage preservation or any hackathon project, Cloud Run is definitely a game-changer!&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Check out our GitHub repo:&lt;/strong&gt;&lt;br&gt;


&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gracetyy" rel="noopener noreferrer"&gt;
        gracetyy
      &lt;/a&gt; / &lt;a href="https://github.com/gracetyy/CraftscapeHK" rel="noopener noreferrer"&gt;
        CraftscapeHK
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Cultural experience platform preserving Hong Kong's disappearing traditional crafts through AR experiences, and AI-assisted custom design creation with real-world artisans to bring ideas to life.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Craftscape HK (藝守)&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Live Demo&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Try our app on &lt;a href="https://craftscape-hk.vercel.app/" rel="nofollow noopener noreferrer"&gt;https://craftscape-hk.vercel.app/&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Inspiration&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Hong Kong’s traditional crafts—such as &lt;strong&gt;hand-carved mahjong tiles, painted porcelain, cheongsam, and neon sign&lt;/strong&gt;—are fading due to shrinking markets and an aging artisan community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More than 70%&lt;/strong&gt; of craft shops have shut in recent years as demand wanes and rents spike, typical &lt;strong&gt;revenues have fallen 30–50%&lt;/strong&gt; amid mass-produced competition, and &lt;strong&gt;80% of artisans&lt;/strong&gt; say their children won’t continue the trade because of long hours, low pay, and little recognition.&lt;/p&gt;

&lt;p&gt;We wanted to build a bridge between the past and the future, enabling young people and global visitors to not only appreciate but also interact with these disappearing arts, and translating the appreciation into tangible support. &lt;strong&gt;Because the most meaningful way to preserve a craft is to create a thriving economy around it.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Craftscape HK is an &lt;strong&gt;AI + AR e-commerce platform&lt;/strong&gt; where users can:&lt;/p&gt;


&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gracetyy/CraftscapeHK" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





</description>
      <category>ai</category>
      <category>webdev</category>
      <category>gcp</category>
      <category>cloudrunhackathon</category>
    </item>
  </channel>
</rss>
