<?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: William</title>
    <description>The latest articles on DEV Community by William (@nightowl).</description>
    <link>https://dev.to/nightowl</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%2F3687804%2Fe809e257-c3d6-4770-8173-019640ed3560.jpg</url>
      <title>DEV Community: William</title>
      <link>https://dev.to/nightowl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nightowl"/>
    <language>en</language>
    <item>
      <title>TripSync — A Three-Tier Gemma 4 Travel Planner Running Live on Flask</title>
      <dc:creator>William</dc:creator>
      <pubDate>Sun, 10 May 2026 12:52:07 +0000</pubDate>
      <link>https://dev.to/nightowl/-tripsync-a-three-tier-gemma-4-travel-planner-running-live-on-flask-3iki</link>
      <guid>https://dev.to/nightowl/-tripsync-a-three-tier-gemma-4-travel-planner-running-live-on-flask-3iki</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the Gemma 4 Challenge: Build With Gemma 4&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&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%2Falv65c7yv3cztb84sud3.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%2Falv65c7yv3cztb84sud3.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TripSync is a live AI travel planner. You type one sentence — "7 days in Tokyo from Toronto" or "adventure trip for two, hiking and wildlife, off-season" — and it returns three destination cards with match scores, budget ranges, visa info, flight times, and activity suggestions. Then it takes you all the way to a booked trip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The full user journey:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Search&lt;/strong&gt; — plain English, no forms, no dropdowns required ( though we have those too for the planners who like to plan ;) )&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Results&lt;/strong&gt; — three destination cards with everything you need to make a decision. Instant load in Gemma 4 Expert mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Book&lt;/strong&gt; — every card links directly to Google Flights, Skyscanner, Booking.com, Agoda, and Expedia with prefilled searches. Dates and destination already filled in. Click and book.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Plan&lt;/strong&gt; — click "View Detailed Planner" on any card and Gemma 4 builds a full day-by-day itinerary. Breakfast, lunch, dinner. Activities. Hotel recommendations. Tours via Viator. Total budget estimate. Full 5-day plan in about 10 seconds. ( yes, 10 seconds, I was surprised too )&lt;/p&gt;

&lt;p&gt;That's the full loop — from one plain-English sentence to a complete, bookable trip plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://tripsync-ilao.onrender.com" rel="noopener noreferrer"&gt;tripsync-ilao.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Tripsync-justmeMedia/tripsync" rel="noopener noreferrer"&gt;github.com/Tripsync-justmeMedia/tripsync&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Python / Flask · Vanilla HTML/JS · SQLite · Render · Ollama · Gemini API · Groq&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;[GIF — toggle switching from Cloud AI to Gemma 4 Expert, search running, three destination cards appearing, planner loading full 5-day itinerary]&lt;/p&gt;

&lt;p&gt;Switch to &lt;strong&gt;✨ Gemma 4 Expert&lt;/strong&gt; mode on the live site and search "7 days in Tokyo from Toronto." Three destination cards appear almost instantly. Click &lt;strong&gt;🗺️ View Detailed Planner&lt;/strong&gt; on any card and Gemma 4 builds a complete 5-day itinerary in about 10 seconds — day by day, meal by meal, activity by activity.&lt;/p&gt;

&lt;p&gt;About a minute total from one sentence to a complete bookable trip plan. ( that still gets me every time )&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%2Fbcn2k39o7s91zcs848in.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%2Fbcn2k39o7s91zcs848in.png" alt=" " width="800" height="517"&gt;&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%2Foxrm9zxu9kjewc9568cx.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%2Foxrm9zxu9kjewc9568cx.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Gemma 4 — The Intentional Choice
&lt;/h2&gt;

&lt;p&gt;Every search on TripSync hits an AI API. Every destination card, every itinerary, every refinement — that's a call to a cloud model. Free tiers end. Traffic grows. And suddenly the thing you built for enjoyment is costing you money before it's made you a cent. ( we've all seen this movie )&lt;/p&gt;

&lt;p&gt;Gemma 4 solved two problems at once:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost problem&lt;/strong&gt; — Gemma 4 via the Gemini API free tier means zero marginal cost per query for real live users. No traffic spike will break the budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The privacy problem&lt;/strong&gt; — travel data is personal. Budgets, travel dates, who you're travelling with, where you're going. The local Ollama mode means that data never leaves the user's machine. That's a real feature, not a marketing claim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; specifically:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 26B model handles TripSync's strict JSON schema reliably. Every response needs to parse into destination cards with specific fields — city, country, match score, budget, visa info, highlights, flight estimates. Smaller models hallucinate the structure. The 26B gets it right consistently, and the advanced reasoning capability means the destination matching is genuinely good, not just keyword matching.&lt;/p&gt;

&lt;p&gt;For local inference I pulled the full &lt;code&gt;gemma4&lt;/code&gt; model via Ollama (9.6GB) on an M1 MacBook with 16GB unified memory — the real limit of consumer hardware. Cold start is 30-45 seconds. Warm queries: under 1 second. Apple Silicon unified memory punches well above what the spec sheet suggests.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three-Tier Architecture
&lt;/h2&gt;

&lt;p&gt;TripSync runs three AI modes, switchable with one toggle in the header:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☁️ Cloud AI&lt;/strong&gt; — Groq with llama-3.3-70b. Fast, reliable, the default fallback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✨ Gemma 4 Expert&lt;/strong&gt; — &lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; via Gemini API. Full Gemma 4 quality for every live user with zero local setup required. This is the primary mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💻 Local AI (Ollama)&lt;/strong&gt; — full &lt;code&gt;gemma4&lt;/code&gt; model running locally via Ollama. Zero data leaving the device. Requires local setup — see GitHub.&lt;/p&gt;

&lt;p&gt;One toggle. All three live right now on the public site.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gemma 4 via Gemini API with silent fallback:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;GEMINI_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_gemma_api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logging&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No GEMINI_API_KEY found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;call_groq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://generativelanguage.googleapis.com/v1beta/models/gemma-4-26b-a4b-it:generateContent?key=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}]}],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generationConfig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxOutputTokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;
        &lt;span class="p"&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="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gemma API &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; — falling back to Groq&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;call_groq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&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="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parts&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;call_groq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logging&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gemma API error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;call_groq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&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;Local Gemma 4 endpoint:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/api/tripsync-local&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tripsync_local&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Local AI unavailable — is Ollama running?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;
    &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_json_safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Could not parse response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed&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;Frontend toggle — three modes, one click:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modes&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;cloud&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;gemma&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;local&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;labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;☁️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cloud AI&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;gemma&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✨&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Gemma 4 Expert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;💻&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Local AI (Ollama)&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;function&lt;/span&gt; &lt;span class="nf"&gt;cycleAIMode&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;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tripsync_ai_mode&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;cloud&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;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;modes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&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;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;modes&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;modes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tripsync_ai_mode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;updateToggleUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&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;
  
  
  Local Setup (For 💻 Local AI Mode)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Clone the repo&lt;/span&gt;
git clone https://github.com/Tripsync-justmeMedia/tripsync
&lt;span class="nb"&gt;cd &lt;/span&gt;tripsync

&lt;span class="c"&gt;# 2. Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# 3. Pull Gemma 4 via Ollama (9.6GB — grab a coffee)&lt;/span&gt;
ollama pull gemma4

&lt;span class="c"&gt;# 4. Add your API key to .env&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"GROQ_API_KEY=your_key_here"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env

&lt;span class="c"&gt;# 5. Run&lt;/span&gt;
python3 server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:5001&lt;/code&gt;, switch to 💻 Local AI mode, search anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware requirements:&lt;/strong&gt; 16GB RAM minimum. M1/M2 Mac recommended. The unified memory architecture handles the 9.6GB model well. ( Intel Mac with 16GB will be slower but workable )&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest Performance Notes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Search Results&lt;/th&gt;
&lt;th&gt;Full Planner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;☁️ Cloud AI (Groq)&lt;/td&gt;
&lt;td&gt;~3-5 seconds&lt;/td&gt;
&lt;td&gt;~8 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✨ Gemma 4 Expert&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;~10-12 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💻 Local AI (cold)&lt;/td&gt;
&lt;td&gt;30-45 seconds&lt;/td&gt;
&lt;td&gt;30-45 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💻 Local AI (warm)&lt;/td&gt;
&lt;td&gt;Under 1 second&lt;/td&gt;
&lt;td&gt;Under 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gemma 4 Expert on the live site is actually faster than Cloud AI for destination search. ( did not expect that )&lt;/p&gt;

&lt;p&gt;The local cold start is real — 30-45 seconds while Ollama loads the model into memory. After that it's instant. Like anything in life, the first run needs to fill all the empty spaces. After that it's just use and maintain.&lt;/p&gt;

&lt;p&gt;Silent fallback is in place throughout — if Gemma API rate limits or times out, Groq catches it. Users never see an error.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Gemma 4 Unlocked
&lt;/h2&gt;

&lt;p&gt;Before this build TripSync had one AI mode. Every query left the user's machine. Free tier limits were a ceiling on growth.&lt;/p&gt;

&lt;p&gt;After Gemma 4:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every live user gets Gemma 4 quality via the Expert mode — no local setup, no friction&lt;/li&gt;
&lt;li&gt;Users who want true local inference have a working path via Ollama&lt;/li&gt;
&lt;li&gt;The architecture scales — local for privacy, API for quality, cloud for speed and fallback&lt;/li&gt;
&lt;li&gt;Zero marginal cost on the Gemini free tier means traffic growth doesn't trigger an infrastructure bill
Gemma 4 didn't just add a feature. It changed the architecture of the whole app and removed the cost ceiling that every solo builder worries about at 2am. ( and yes, I do worry about it at 2am, in my housecoat, in Minesing Ontario )&lt;/li&gt;
&lt;/ul&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%2Fd5weij5y9tb8ucv1k0p2.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%2Fd5weij5y9tb8ucv1k0p2.png" alt=" " width="800" height="517"&gt;&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%2Fg3d5bqubr4gkwvm7if9s.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%2Fg3d5bqubr4gkwvm7if9s.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://tripsync-ilao.onrender.com" rel="noopener noreferrer"&gt;tripsync-ilao.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Switch to &lt;strong&gt;✨ Gemma 4 Expert&lt;/strong&gt; mode using the toggle in the header&lt;/li&gt;
&lt;li&gt;Search "7 days in Tokyo from Toronto" or anything you wish.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;🗺️ View Detailed Planner&lt;/strong&gt; on any result&lt;/li&gt;
&lt;li&gt;Watch Gemma 4 build a complete trip plan in about 10 seconds
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Tripsync-justmeMedia/tripsync" rel="noopener noreferrer"&gt;github.com/Tripsync-justmeMedia/tripsync&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;William Commu — Just Me Media&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Minesing, Ontario&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://dev.to/nightowl"&gt;@nightowl on DEV&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Built at night. In a housecoat. With stubbornness. ✌️&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gemma</category>
      <category>gemmachallenge</category>
      <category>webdev</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title>Gemma 4 on Real Hardware: Local Inference, Cloud API, and a Three-Tier Architecture That Actually Works</title>
      <dc:creator>William</dc:creator>
      <pubDate>Sat, 09 May 2026 22:13:58 +0000</pubDate>
      <link>https://dev.to/nightowl/no-degree-no-team-no-api-bill-i-shipped-gemma-4-into-my-travel-app-at-58-and-so-can-you-gemma-3oi7</link>
      <guid>https://dev.to/nightowl/no-degree-no-team-no-api-bill-i-shipped-gemma-4-into-my-travel-app-at-58-and-so-can-you-gemma-3oi7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the Gemma 4 Challenge: Write About Gemma 4&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Let me be straight with you before we get into any of this.&lt;/p&gt;

&lt;p&gt;I am 58 years old. Retired. I build products for enjoyment — income is just a by-product of the effort. ( and yes that took me a long time to figure out, but once you do, everything changes ) I live in Minesing, Ontario. I have a cottage in Bracebridge. I work on projects at night, usually with a smoke and in my housecoat. ( don't judge me, it works )&lt;/p&gt;

&lt;p&gt;I have no computer science degree, no coding background, and no team. I am what people in this community politely call a "vibe coder" — which is a kind way of saying I build things with AI tools and a terminal and a lot of stubbornness. And push through. ( and push back ;) ) Stubbornness is 100% non-negotiable when you're working long hours with different AIs at 58. The tools are incredible and they will also confidently break your app and tell you it's your fault. Every. Single. Time. ( you get used to it, I promise )&lt;/p&gt;

&lt;p&gt;Over the last year I built three live products from scratch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Events Arena&lt;/strong&gt; — a live sports prediction platform with Soccer, NHL, and expandable arenas for any type of event, from organized sports to internet creator events ( yes that last part is a whole thing now )&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaS Price DB&lt;/strong&gt; — a REST API tracking pricing data for 1,000+ B2B SaaS tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TripSync&lt;/strong&gt; — an AI travel planner that takes plain-English trip descriptions and returns real destinations with flight estimates and booking links
Zero users on most of them. I wrote about that honestly on May 9th. ( zero judgement if you go read it, it's a fun honest post ) But here's what I didn't fully explain in that post:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;I built TripSync for myself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every winter I travel for 3-4 months. Multiple countries. Multiple cities. I move around — I don't sit in one place and call it a vacation. Canadian winters are not for me anymore, and we've done Mexico, the States, and DR. ( Canadian winters, not for me, hard pass, no thank you, never again ) Planning those trips used to mean hours of browser tabs, scattered booking sites, trying to hold flight prices and hotel options and visa requirements in my head at the same time — while also figuring out what order to visit cities in so the flights make sense and we get the best experience at the lowest cost. Premium economy for long flights, economy for short ones. ( yes I have a system, don't we all )&lt;/p&gt;

&lt;p&gt;TripSync was my solution to my own problem. I am the user. I use it to plan my own travel — this coming January through May 2027 and any trips between now and then. Whether anyone else ever uses it is a question I'm still working on. ( working on it, not losing sleep over it, there is a difference )&lt;/p&gt;

&lt;p&gt;This post is about what I tried to add to it during the Gemma 4 Challenge, and what I actually found. Not what I hoped to find. What I actually found. ( spoiler: I was surprised )&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fear Every Solo Builder Has But Won't Say Out Loud
&lt;/h2&gt;

&lt;p&gt;I'll be honest about why I'm here because that's the kind of post this is.&lt;/p&gt;

&lt;p&gt;I'm in this contest for three reasons: the prize money, the exposure for my projects, and genuinely wanting to help other builders who are in the same position I was six months ago. All three matter. None of them are secret. ( refreshing right? )&lt;/p&gt;

&lt;p&gt;But the thing that got me paying attention to Gemma 4 specifically? The API bill.&lt;/p&gt;

&lt;p&gt;I try to build all my projects at zero budget. When a project makes some income, I reinvest a part of that into growth. If it makes nothing, I don't put myself in a worse position than I was before the project existed. That's the rule. ( simple rule, hard to follow when you're excited about an idea at 2am, but still the rule )&lt;/p&gt;

&lt;p&gt;Every search on TripSync hits an AI API. Every destination card, every itinerary, every refinement — that's a call to a cloud model. Right now I'm on free tiers. But free tiers end. Traffic grows. And suddenly the thing you built for enjoyment is costing you money before it's made you a cent. ( we've all seen this movie and it doesn't end well )&lt;/p&gt;

&lt;p&gt;So when the Gemma 4 Challenge came up — Google's open model family that runs locally, for free, no API calls, no data leaving the device — I thought: this is the exact problem I think about. Let me actually try it on a real app.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Gemma 4 Is, In Plain English
&lt;/h2&gt;

&lt;p&gt;Skip this if you already know. Stay if you're like me and need someone to explain it without assuming a PhD is hiding in your back pocket. ( it's not, I checked )&lt;/p&gt;

&lt;p&gt;Gemma 4 is a family of AI models Google has released as open weights. You download the model and run it on your own hardware. No subscription. No per-token charges. No sending user data to a third-party server. ( yes, really, I know, wild )&lt;/p&gt;

&lt;p&gt;Four models in the family:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;E2B / E4B&lt;/strong&gt; — tiny, run on phones and Raspberry Pis ( yes a Raspberry Pi, yes that little $75 thing )&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12B&lt;/strong&gt; — sweet spot for most developer laptops&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;27B dense&lt;/strong&gt; — the workhorse, needs more RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;26B MoE&lt;/strong&gt; — efficient, built for high-throughput reasoning
I have a MacBook Pro M1 with 16GB of unified memory. Not a beast of a machine. The kind of setup a lot of solo builders actually have sitting on their desk next to a cold coffee. ( always a cold coffee )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The question I wanted to answer: &lt;strong&gt;can Gemma 4 run meaningfully on real hardware that real people actually own?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Right Model
&lt;/h2&gt;

&lt;p&gt;Apple M1 Pro with 16GB unified memory has a practical ceiling. Push past it and the system starts swapping to SSD — which turns a 1-second response into a several-minute crawl. Not usable. ( I tried to ignore this ceiling, the ceiling won )&lt;/p&gt;

&lt;p&gt;I pulled &lt;code&gt;gemma4&lt;/code&gt; via Ollama — the full default model, 9.6GB. On my M1 with 16GB unified memory, this is right at the edge of what's practical, and that's intentional. I wanted the real performance story at the limit of consumer hardware, not on some server with 64GB of RAM that none of us have. ( none of us have that, right? right? )&lt;/p&gt;

&lt;p&gt;What I didn't fully appreciate until I tried it: Apple Silicon unified memory isn't traditional RAM. The CPU and GPU share the same pool, and Apple's neural engine accelerates inference in a way that punches above what the raw numbers suggest. The model performs noticeably better on M1 than the spec sheet implies. ( Apple does some things right, I'll give them that )&lt;/p&gt;

&lt;p&gt;The choice wasn't "what's the biggest model I can technically load." It was "what's the right model for hardware a solo builder actually owns." That's a different question, and I think it's the more interesting one.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Actually Built — And What I Didn't
&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%2Fl1x0u2v0qq39c76l2qg3.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%2Fl1x0u2v0qq39c76l2qg3.png" alt=" " width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to be honest here because I've read enough contest posts that oversell what was built. ( we all have, no names, you know who you are ) I'm not going to do that to you.&lt;/p&gt;

&lt;p&gt;TripSync runs on Flask on Render. The public site at &lt;a href="https://tripsync-ilao.onrender.com" rel="noopener noreferrer"&gt;tripsync-ilao.onrender.com&lt;/a&gt; runs three AI modes — Cloud AI via Groq, Gemma 4 Expert via the Gemini API, and Local AI via Ollama on your own machine. Live users can experience Gemma 4 right now in Expert mode without any local setup.&lt;/p&gt;

&lt;p&gt;The local Ollama mode requires cloning the repo and running it yourself. That's the honest truth about what "local" means — it runs on your machine, not mine.&lt;/p&gt;

&lt;p&gt;Here's what I added:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Pulled Gemma 4 via Ollama&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull gemma4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9.6GB. I watched the progress bar and thought — this is the whole model. On my laptop. No monthly bill. ( I actually said "wild" out loud to nobody at 2pm on a Saturday, the housecoat was involved )&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Added dedicated local and Gemma API endpoints in server.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/api/tripsync-local&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tripsync_local&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Local AI unavailable — is Ollama running?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;
    &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_json_safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Could not parse response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed&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;3. Added a three-mode toggle to the UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One click cycles through Cloud AI, Gemma 4 Expert, and Local AI. Persists in localStorage. ( one click, that's it, I love when things are actually simple )&lt;/p&gt;

&lt;p&gt;Three changes. Three modes. I'm a vibe coder — if I can't understand what I'm building, I can't build it. Simple on purpose. Always. ( complexity is not a flex, it's a future problem you're creating for yourself )&lt;/p&gt;




&lt;h2&gt;
  
  
  What Actually Happened When I Ran It
&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%2Fkzm6hywnqtwa8nzlvy7u.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%2Fkzm6hywnqtwa8nzlvy7u.png" alt=" " width="800" height="517"&gt;&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%2Foo8u3hgjf9pqjxpoxm78.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%2Foo8u3hgjf9pqjxpoxm78.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like anything in life — the first run, the startup, needs to pre-fill all the empty spaces. Cold start on a 9.6GB model takes 30-45 seconds. The spinner spins. You sit there. You wonder if you broke something. ( you probably did break something, but not this time )&lt;/p&gt;

&lt;p&gt;Then it responds.&lt;/p&gt;

&lt;p&gt;And after that it's just use and maintain. Once Gemma 4 is warm in memory: &lt;strong&gt;under 1 second per query.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I sat back on a Saturday afternoon with the light coming through the window and just looked at the screen for a moment. A model running entirely on my MacBook — no internet required for the inference — returning detailed travel itineraries faster than a cloud API call. ( I may have done a small fist pump, I'm not confirming or denying )&lt;/p&gt;

&lt;p&gt;I tested it with Thailand. Seven days, solo traveller, flying from Toronto, budget accommodation. Chiang Mai came back as the top result. I've actually been to Chiang Mai. The recommendations — Doi Suthep sunrise, Khao Soi noodles, the elephant sanctuary, the night bazaar — those are real. That captures the vibes of that city in a way that only someone who's actually been there would recognize. ( Gemma 4 has not been to Chiang Mai, and yet, somehow, it gets it )&lt;/p&gt;

&lt;p&gt;I expected to write a post about why it didn't quite work. That's not the post I'm writing. ( surprised myself on this one )&lt;/p&gt;




&lt;h2&gt;
  
  
  The API Cost Math
&lt;/h2&gt;

&lt;p&gt;On Groq's free tier: roughly 250-333 TripSync searches per day before hitting limits. For a travel app with real traffic that's nothing — a slow Tuesday afternoon. ( a very slow Tuesday )&lt;/p&gt;

&lt;p&gt;With Gemma 4 running locally: unlimited. Zero marginal cost. The only constraint is hardware I already own.&lt;/p&gt;

&lt;p&gt;The honest caveat: my local Gemma 4 runs on my MacBook, not on Render's servers. Getting it in front of real public users as a true local experience requires either a VPS with enough RAM or the user running it themselves. What I've proven is that &lt;strong&gt;Gemma 4 is production-quality for this use case.&lt;/strong&gt; The remaining work is infrastructure, not model capability. ( important distinction, write that down )&lt;/p&gt;




&lt;h2&gt;
  
  
  The Privacy Thing I Didn't Expect to Care About
&lt;/h2&gt;

&lt;p&gt;I travel a lot. I type things like "romantic trip for two, budget $4,000, leaving Toronto in January, somewhere warm, private villa preferred" into travel tools.&lt;/p&gt;

&lt;p&gt;That's personal. Budget. Travel dates. Who I'm with. Where I'm going.&lt;/p&gt;

&lt;p&gt;Right now the cloud modes send that to an API. Those services have privacy policies. I'm not suggesting anything nefarious. But the data leaves my machine. ( it just does, that's the reality )&lt;/p&gt;

&lt;p&gt;When I ran the same search in Local AI mode — knowing it went from browser to local Flask to Ollama on my CPU and back, never touching an external server — I felt something I didn't expect.&lt;/p&gt;

&lt;p&gt;Relief. Genuine relief.&lt;/p&gt;

&lt;p&gt;There's a version of TripSync I want to build where users who care about privacy actually have it as a real, working, verifiable option. Not a marketing claim. Gemma 4 makes that possible. Given that I built this tool for my own travel planning, that's not abstract to me. It's personal. ( built it for me, privacy matters to me, simple )&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pre-warm on server start&lt;/strong&gt; — eliminate that cold-start wait for local mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance comparison UI&lt;/strong&gt; — show users side-by-side response times, let them choose with real information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production local deployment&lt;/strong&gt; — VPS with enough RAM to serve Gemma 4 to real public users without local setup ( the goal, working toward it )
The live app: &lt;a href="https://tripsync-ilao.onrender.com" rel="noopener noreferrer"&gt;tripsync-ilao.onrender.com&lt;/a&gt;
The code: &lt;a href="https://github.com/Tripsync-justmeMedia/tripsync" rel="noopener noreferrer"&gt;github.com/Tripsync-justmeMedia/tripsync&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I'd Actually Tell Another Builder
&lt;/h2&gt;

&lt;p&gt;Not a motivational poster. Real advice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do you enjoy?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build something around that. Once that's done — if you enjoyed the process of building it, then building anything is possible for you. Keep going. If you didn't enjoy it, maybe the answer isn't more building. Maybe it's marketing, or social media, or brand building. Or maybe nothing digital at all — maybe it's time to focus on physical things. A real community with real people. Writing stories, keeping a blog. Getting outside and touching grass. ( seriously, touch grass, it resets everything )&lt;/p&gt;

&lt;p&gt;When things feel tough — step away. Take a breath. It resets you mentally, and that's when most times the right choices come to the top. ( I have learned this the hard way more than once )&lt;/p&gt;

&lt;p&gt;The point isn't to become a developer. The point is to find what gives you energy and do more of that.&lt;/p&gt;

&lt;p&gt;For me, it's building things at night in my housecoat in Minesing with Gemma 4 running on my MacBook. Zero API bill. Zero regrets.&lt;/p&gt;

&lt;p&gt;Be good to yourself and others. ☮️&lt;/p&gt;




&lt;p&gt;&lt;em&gt;William Commu — Just Me Media&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Minesing, Ontario | Cottage in Bracebridge&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://dev.to/nightowl"&gt;@nightowl on DEV&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;TripSync: &lt;a href="https://tripsync-ilao.onrender.com" rel="noopener noreferrer"&gt;tripsync-ilao.onrender.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gemmachallenge</category>
      <category>gemma</category>
      <category>devchallenge</category>
      <category>webdev</category>
    </item>
    <item>
      <title>3 products. 1 year. Zero users. Here's my honest update at 58 and what I'm doing differently</title>
      <dc:creator>William</dc:creator>
      <pubDate>Sat, 09 May 2026 17:28:29 +0000</pubDate>
      <link>https://dev.to/nightowl/3-products-1-year-zero-users-heres-my-honest-update-at-58-and-what-im-doing-differently-5cji</link>
      <guid>https://dev.to/nightowl/3-products-1-year-zero-users-heres-my-honest-update-at-58-and-what-im-doing-differently-5cji</guid>
      <description>&lt;p&gt;In the last year I taught myself to build three complete products from scratch using AI as my development partner.&lt;br&gt;
A live sports prediction platform. An AI travel planner. A SaaS pricing intelligence API.&lt;br&gt;
All live. All polished. Zero paying users across all three.&lt;br&gt;
I'm not bitter about it. I learned more in one year than most people learn in five. But I'm being honest with myself now — I'm a builder, not a marketer. I love the craft. I don't love finding customers.&lt;br&gt;
So I'm doing something different. I'm looking for a co-founder who has the customer relationships and the problem. I'll build the solution.&lt;br&gt;
I build. You sell. We split it fairly.&lt;br&gt;
Three live products to prove I ship: sportsprophecyapp.com | tripsync-ilao.onrender.com | saaspricedb.com&lt;br&gt;
Company: Just Me Media | Canada | Remote friendly&lt;br&gt;
If any of this resonates — drop a comment or reach out.&lt;br&gt;
MVNFRWRD. 🦉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cofounder</category>
      <category>startup</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>3 products. 1 year. Zero users. Here's my honest update at 58 and what I'm doing differently</title>
      <dc:creator>William</dc:creator>
      <pubDate>Sat, 09 May 2026 17:28:29 +0000</pubDate>
      <link>https://dev.to/nightowl/3-products-1-year-zero-users-heres-my-honest-update-at-58-and-what-im-doing-differently-emo</link>
      <guid>https://dev.to/nightowl/3-products-1-year-zero-users-heres-my-honest-update-at-58-and-what-im-doing-differently-emo</guid>
      <description>&lt;p&gt;In the last year I taught myself to build three complete products from scratch using AI as my development partner.&lt;br&gt;
A live sports prediction platform. An AI travel planner. A SaaS pricing intelligence API.&lt;br&gt;
All live. All polished. Zero paying users across all three.&lt;br&gt;
I'm not bitter about it. I learned more in one year than most people learn in five. But I'm being honest with myself now — I'm a builder, not a marketer. I love the craft. I don't love finding customers.&lt;br&gt;
So I'm doing something different. I'm looking for a co-founder who has the customer relationships and the problem. I'll build the solution.&lt;br&gt;
I build. You sell. We split it fairly.&lt;br&gt;
Three live products to prove I ship: sportsprophecyapp.com | tripsync-ilao.onrender.com | saaspricedb.com&lt;br&gt;
Company: Just Me Media | Canada | Remote friendly&lt;br&gt;
If any of this resonates — drop a comment or reach out.&lt;br&gt;
MVNFRWRD. 🦉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cofounder</category>
      <category>startup</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title># SaaSPriceDB: Real-Time Pricing API – My Vibe-Coding Journey from Zero Experience at 58 🦉</title>
      <dc:creator>William</dc:creator>
      <pubDate>Mon, 05 Jan 2026 06:20:36 +0000</pubDate>
      <link>https://dev.to/nightowl/-saaspricedb-real-time-pricing-api-my-vibe-coding-journey-from-zero-experience-at-58-koe</link>
      <guid>https://dev.to/nightowl/-saaspricedb-real-time-pricing-api-my-vibe-coding-journey-from-zero-experience-at-58-koe</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the DEV's Worldwide Show and Tell Challenge Presented by Mux&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hey DEV community 👋&lt;/p&gt;

&lt;p&gt;I'm William, 58 years old, solo founder of Just Me Media, and a proud NightOwl (Claude even certified me — I’ve got some really funny screen recordings of me and Claude going back and forth 😂). Most nights around 3 a.m., you’ll find me in my house coat, talking to LLMs like Claude, ChatGPT, and Grok — describing ideas and watching them build real software. I call it &lt;strong&gt;vibe coding&lt;/strong&gt;: no syntax wars, just prompts, vibes, and results.&lt;/p&gt;

&lt;p&gt;Two months ago, I had &lt;strong&gt;zero coding experience&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;SaaSPriceDB&lt;/strong&gt; — a clean, production-ready REST API that delivers structured, real-time pricing data for &lt;strong&gt;185+&lt;/strong&gt; popular SaaS tools (and growing fast): Slack, Shopify, Stripe, Salesforce, Notion, GitHub, Zoom, MongoDB, and many more.&lt;/p&gt;

&lt;p&gt;It solves a real pain point: developers waste hours scraping fragile pricing pages that change frequently and break scrapers constantly.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Daily automatic updates + price change detection&lt;/li&gt;
&lt;li&gt;Reliable structured JSON — no more manual maintenance or broken scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free public preview endpoint&lt;/strong&gt; (no signup, no API key — shows 5 sample products: Slack, Notion, Zoom, Asana, GitHub): &lt;a href="https://api.saaspricedb.com/api/free-preview" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/api/free-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interactive Swagger API docs (explore structure publicly): &lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full access via API key (paid plans or judge special key) for 185+ tools, historical data, higher limits&lt;/li&gt;
&lt;li&gt;Live site: &lt;a href="https://saaspricedb.com" rel="noopener noreferrer"&gt;https://saaspricedb.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s in launch mode with limited-time early access pricing — coverage is expanding rapidly.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Pitch Video
&lt;/h2&gt;

&lt;p&gt;Here’s my under-1-minute talking-head pitch (recorded and edited by a total beginner in iMovie):&lt;/p&gt;

&lt;p&gt;

&lt;iframe src="https://player.mux.com/Aiq01iYM01rM7Vh9TLAAvib8jZt9uxVpDbdIBMP7GP01Ds" width="710" height="399"&gt;
&lt;/iframe&gt;



&lt;/p&gt;

&lt;p&gt;My 1st try was like 4 minutes — this was the hardest part of the challenge for me! 😅&lt;br&gt;&lt;br&gt;
In 60 seconds or less: the problem I solved,what makes SaaSPriceDB special,some of the features, real time walk though on the ease of setup and a quick look at how it works.&lt;br&gt;&lt;br&gt;
(Hosted, sub titles &amp;amp; delivered smoothly via Mux — perfect for indie pitches! Will add quick app demo footage soon for the &lt;strong&gt;Enterprise Package&lt;/strong&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo &amp;amp; Testing (Super Easy – No Signup Needed!)
&lt;/h2&gt;

&lt;p&gt;Judges and community: please test away!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instant free preview&lt;/strong&gt; (public JSON, no key required — 5 samples): &lt;a href="https://api.saaspricedb.com/api/free-preview" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/api/free-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Swagger docs&lt;/strong&gt; (view endpoints &amp;amp; structure): &lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live website: &lt;a href="https://saaspricedb.com" rel="noopener noreferrer"&gt;https://saaspricedb.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: Full dataset requires an API key — see judges section below for easy full access.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Note for DEV Challenge Judges – Full Access Made Easy!
&lt;/h3&gt;

&lt;p&gt;Thanks for reviewing! 🚀  &lt;/p&gt;

&lt;p&gt;To test the full power (185+ tools, historical price changes, high enterprise limits, etc.):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The site uses an &lt;strong&gt;API key system&lt;/strong&gt; (no traditional signup/login buttons visible on the landing page).&lt;/li&gt;
&lt;li&gt;For instant full access: reply or DM me here on DEV with "judge access" — I'll send you:

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;special enterprise-level API key&lt;/strong&gt; (high limits, full features)&lt;/li&gt;
&lt;li&gt;OR a &lt;strong&gt;magic link&lt;/strong&gt; to the dashboard where the Judges' Cheat Sheet auto-loads with your key, interactive tester, Swagger guide, test card (4242 4242 4242 4242), etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Once you have the key, authorize in Swagger (&lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;) → Bearer token → test any endpoint (e.g. /pricing/).&lt;/li&gt;

&lt;li&gt;Close any welcome popup with "X" or "Got it, let's explore!"&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Zero friction — happy to send instantly. Appreciate your time and feedback!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Story Behind It
&lt;/h2&gt;

&lt;p&gt;My first project was &lt;a href="https://www.sportsprophecyapp.com/" rel="noopener noreferrer"&gt;https://www.sportsprophecyapp.com/&lt;/a&gt; — my vision of a user/sponsor ecosystem that’s adaptable for any event, television show, or social media moment — a fun, no-gambling sports prediction platform where fans pick winners for sponsor prizes. I learned massively through failure, late-night fixes, and rebuilds… but realized passion alone isn’t enough.&lt;/p&gt;

&lt;p&gt;I needed to solve a &lt;strong&gt;real problem people are already searching for&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I asked Claude one night:&lt;br&gt;&lt;br&gt;
“What’s a painful problem we can solve with a simple tool?”&lt;/p&gt;

&lt;p&gt;The answer: fragile SaaS pricing scrapers that devs hate maintaining.&lt;/p&gt;

&lt;p&gt;When I found the domain saaspricedb.com had no owner and realized the branding would be insane… well, I was hooked on the idea to build this.&lt;/p&gt;

&lt;p&gt;That same night, &lt;strong&gt;SaaSPriceDB&lt;/strong&gt; was born — fully vibe-coded with LLM help from start to finish.&lt;/p&gt;

&lt;p&gt;If a 58-year-old beginner with zero tech background can ship a production API… anyone can.&lt;br&gt;&lt;br&gt;
The fails, the late nights, the small wins — they’re all part of the story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My advice for late starters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Use the tools. Keep trying. Fail, get up, keep moving forward. Enjoy the journey. All of us have the same final destination; it’s the journey that sets us apart as individuals.&lt;/p&gt;

&lt;p&gt;I’d love your honest feedback, suggestions for the next SaaS tool to add, or your own vibe-coding stories!&lt;br&gt;&lt;br&gt;
Early testers/collaborators for feedback, ratings, social proof, indie SaaS ideas — please say hi! 🦉&lt;br&gt;&lt;br&gt;
(Also open to the idea of a collaboration with others on a % basis to grow this into something that truly benefits others.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Built entirely via vibe-coding: describe → prompt LLMs → refine → deploy&lt;/li&gt;
&lt;li&gt;Daily cron jobs for updates + change detection&lt;/li&gt;
&lt;li&gt;Simple REST API with structured JSON (public preview + authenticated full access)&lt;/li&gt;
&lt;li&gt;Designed to scale as more tools are added&lt;/li&gt;
&lt;li&gt;Through feedback, this tool truly grows to solve problems, save time, and create opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use of Mux (Bonus Category)
&lt;/h2&gt;

&lt;p&gt;I used Mux to host and deliver my pitch video reliably — fast loading, great quality, and zero hassle for a beginner creator. Simple but effective, and there are more options I’ll learn and use with upcoming posts!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next: Sports Prophecy
&lt;/h2&gt;

&lt;p&gt;While building SaaSPriceDB, was solving a problem. Im back to building and launching &lt;strong&gt;Sports Prophecy&lt;/strong&gt; my 1st app ever&lt;br&gt;
(&lt;a href="https://www.sportsprophecyapp.com" rel="noopener noreferrer"&gt;https://www.sportsprophecyapp.com&lt;/a&gt;) — a real-time community prediction &lt;br&gt;
platform for sports, events, and live streaming.&lt;/p&gt;

&lt;p&gt;Same vibe-coding approach. Same "build with AI, iterate fast" philosophy.&lt;/p&gt;

&lt;p&gt;Early users welcome. Check it out and let me know what you think!&lt;/p&gt;

&lt;p&gt;Thanks for reading, watching, and joining me on this journey. Still learning every day. &lt;strong&gt;NightOwl&lt;/strong&gt; 🦉&lt;/p&gt;

&lt;h1&gt;
  
  
  showdev #saas #api #nocode #devchallenge #muxchallenge #webdev #Anthropic #Google #Antigravity
&lt;/h1&gt;

</description>
      <category>muxchallenge</category>
      <category>showdev</category>
      <category>beginners</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title># SaaSPriceDB: Real-Time Pricing API – My Vibe-Coding Journey from Zero Experience at 58 🦉</title>
      <dc:creator>William</dc:creator>
      <pubDate>Thu, 01 Jan 2026 10:28:43 +0000</pubDate>
      <link>https://dev.to/nightowl/saaspricedb-real-time-pricing-api-my-vibe-coding-journey-from-zero-experience-at-58-4i17</link>
      <guid>https://dev.to/nightowl/saaspricedb-real-time-pricing-api-my-vibe-coding-journey-from-zero-experience-at-58-4i17</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the DEV's Worldwide Show and Tell Challenge Presented by Mux&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hey DEV community 👋&lt;/p&gt;

&lt;p&gt;I'm William, 58 years old, solo founder of Just Me Media, and a proud NightOwl (Claude even certified me — I’ve got some really funny screen recordings of me and Claude going back and forth 😂). Most nights around 3 a.m., you’ll find me in my house coat, talking to LLMs like Claude, ChatGPT, and Grok — describing ideas and watching them build real software. I call it &lt;strong&gt;vibe coding&lt;/strong&gt;: no syntax wars, just prompts, vibes, and results.&lt;/p&gt;

&lt;p&gt;Two months ago, I had &lt;strong&gt;zero coding experience&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;SaaSPriceDB&lt;/strong&gt; — a clean, production-ready REST API that delivers structured, real-time pricing data for &lt;strong&gt;185+&lt;/strong&gt; popular SaaS tools (and growing fast): Slack, Shopify, Stripe, Salesforce, Notion, GitHub, Zoom, MongoDB, and many more.&lt;/p&gt;

&lt;p&gt;It solves a real pain point: developers waste hours scraping fragile pricing pages that change frequently and break scrapers constantly.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Daily automatic updates + price change detection&lt;/li&gt;
&lt;li&gt;Reliable structured JSON — no more manual maintenance or broken scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free public preview endpoint&lt;/strong&gt; (no signup, no API key — shows 5 sample products: Slack, Notion, Zoom, Asana, GitHub): &lt;a href="https://api.saaspricedb.com/api/free-preview" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/api/free-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interactive Swagger API docs (explore structure publicly): &lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full access via API key (paid plans or judge special key) for 185+ tools, historical data, higher limits&lt;/li&gt;
&lt;li&gt;Live site: &lt;a href="https://saaspricedb.com" rel="noopener noreferrer"&gt;https://saaspricedb.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s in launch mode with limited-time early access pricing — coverage is expanding rapidly.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Pitch Video
&lt;/h2&gt;

&lt;p&gt;Here’s my under-1-minute talking-head pitch (recorded and edited by a total beginner in iMovie):&lt;/p&gt;

&lt;p&gt;

&lt;iframe src="https://player.mux.com/Aiq01iYM01rM7Vh9TLAAvib8jZt9uxVpDbdIBMP7GP01Ds" width="710" height="399"&gt;
&lt;/iframe&gt;



&lt;/p&gt;

&lt;p&gt;My 1st try was like 4 minutes — this was the hardest part of the challenge for me! 😅&lt;br&gt;&lt;br&gt;
In 60 seconds or less: the problem I solved,what makes SaaSPriceDB special,some of the features, real time walk though on the ease of setup and a quick look at how it works.&lt;br&gt;&lt;br&gt;
(Hosted, sub titles &amp;amp; delivered smoothly via Mux — perfect for indie pitches! Will add quick app demo footage soon for the &lt;strong&gt;Enterprise Package&lt;/strong&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo &amp;amp; Testing (Super Easy – No Signup Needed!)
&lt;/h2&gt;

&lt;p&gt;Judges and community: please test away!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instant free preview&lt;/strong&gt; (public JSON, no key required — 5 samples): &lt;a href="https://api.saaspricedb.com/api/free-preview" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/api/free-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Swagger docs&lt;/strong&gt; (view endpoints &amp;amp; structure): &lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live website: &lt;a href="https://saaspricedb.com" rel="noopener noreferrer"&gt;https://saaspricedb.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: Full dataset requires an API key — see judges section below for easy full access.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Note for DEV Challenge Judges – Full Access Made Easy!
&lt;/h3&gt;

&lt;p&gt;Thanks for reviewing! 🚀  &lt;/p&gt;

&lt;p&gt;To test the full power (185+ tools, historical price changes, high enterprise limits, etc.):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The site uses an &lt;strong&gt;API key system&lt;/strong&gt; (no traditional signup/login buttons visible on the landing page).&lt;/li&gt;
&lt;li&gt;For instant full access: reply or DM me here on DEV with "judge access" — I'll send you:

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;special enterprise-level API key&lt;/strong&gt; (high limits, full features)&lt;/li&gt;
&lt;li&gt;OR a &lt;strong&gt;magic link&lt;/strong&gt; to the dashboard where the Judges' Cheat Sheet auto-loads with your key, interactive tester, Swagger guide, test card (4242 4242 4242 4242), etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Once you have the key, authorize in Swagger (&lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://api.saaspricedb.com/docs" rel="noopener noreferrer"&gt;https://api.saaspricedb.com/docs&lt;/a&gt;) → Bearer token → test any endpoint (e.g. /pricing/).&lt;/li&gt;

&lt;li&gt;Close any welcome popup with "X" or "Got it, let's explore!"&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Zero friction — happy to send instantly. Appreciate your time and feedback!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Story Behind It
&lt;/h2&gt;

&lt;p&gt;My first project was &lt;a href="https://www.sportsprophecyapp.com/" rel="noopener noreferrer"&gt;https://www.sportsprophecyapp.com/&lt;/a&gt; — my vision of a user/sponsor ecosystem that’s adaptable for any event, television show, or social media moment — a fun, no-gambling sports prediction platform where fans pick winners for sponsor prizes. I learned massively through failure, late-night fixes, and rebuilds… but realized passion alone isn’t enough.&lt;/p&gt;

&lt;p&gt;I needed to solve a &lt;strong&gt;real problem people are already searching for&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I asked Claude one night:&lt;br&gt;&lt;br&gt;
“What’s a painful problem we can solve with a simple tool?”&lt;/p&gt;

&lt;p&gt;The answer: fragile SaaS pricing scrapers that devs hate maintaining.&lt;/p&gt;

&lt;p&gt;When I found the domain saaspricedb.com had no owner and realized the branding would be insane… well, I was hooked on the idea to build this.&lt;/p&gt;

&lt;p&gt;That same night, &lt;strong&gt;SaaSPriceDB&lt;/strong&gt; was born — fully vibe-coded with LLM help from start to finish.&lt;/p&gt;

&lt;p&gt;If a 58-year-old beginner with zero tech background can ship a production API… anyone can.&lt;br&gt;&lt;br&gt;
The fails, the late nights, the small wins — they’re all part of the story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My advice for late starters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Use the tools. Keep trying. Fail, get up, keep moving forward. Enjoy the journey. All of us have the same final destination; it’s the journey that sets us apart as individuals.&lt;/p&gt;

&lt;p&gt;I’d love your honest feedback, suggestions for the next SaaS tool to add, or your own vibe-coding stories!&lt;br&gt;&lt;br&gt;
Early testers/collaborators for feedback, ratings, social proof, indie SaaS ideas — please say hi! 🦉&lt;br&gt;&lt;br&gt;
(Also open to the idea of a collaboration with others on a % basis to grow this into something that truly benefits others.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Built entirely via vibe-coding: describe → prompt LLMs → refine → deploy&lt;/li&gt;
&lt;li&gt;Daily cron jobs for updates + change detection&lt;/li&gt;
&lt;li&gt;Simple REST API with structured JSON (public preview + authenticated full access)&lt;/li&gt;
&lt;li&gt;Designed to scale as more tools are added&lt;/li&gt;
&lt;li&gt;Through feedback, this tool truly grows to solve problems, save time, and create opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use of Mux (Bonus Category)
&lt;/h2&gt;

&lt;p&gt;I used Mux to host and deliver my pitch video reliably — fast loading, great quality, and zero hassle for a beginner creator. Simple but effective, and there are more options I’ll learn and use with upcoming posts!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next: Sports Prophecy
&lt;/h2&gt;

&lt;p&gt;While building SaaSPriceDB, was solving a problem. Im back to building and launching &lt;strong&gt;Sports Prophecy&lt;/strong&gt; my 1st app ever&lt;br&gt;
(&lt;a href="https://www.sportsprophecyapp.com" rel="noopener noreferrer"&gt;https://www.sportsprophecyapp.com&lt;/a&gt;) — a real-time community prediction &lt;br&gt;
platform for sports, events, and live streaming.&lt;/p&gt;

&lt;p&gt;Same vibe-coding approach. Same "build with AI, iterate fast" philosophy.&lt;/p&gt;

&lt;p&gt;Early users welcome. Check it out and let me know what you think!&lt;/p&gt;

&lt;p&gt;Thanks for reading, watching, and joining me on this journey. Still learning every day. &lt;strong&gt;NightOwl&lt;/strong&gt; 🦉&lt;/p&gt;

&lt;h1&gt;
  
  
  showdev #saas #api #nocode #devchallenge #muxchallenge #webdev #Anthropic #Google #Antigravity
&lt;/h1&gt;

</description>
      <category>saas</category>
      <category>api</category>
      <category>showdev</category>
      <category>b2b</category>
    </item>
  </channel>
</rss>
