<?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: Jowi A</title>
    <description>The latest articles on DEV Community by Jowi A (@jowi00000).</description>
    <link>https://dev.to/jowi00000</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%2F3802552%2F4d347498-4291-4263-865d-93ac7a1ec5a7.png</url>
      <title>DEV Community: Jowi A</title>
      <link>https://dev.to/jowi00000</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jowi00000"/>
    <language>en</language>
    <item>
      <title>The G Factor: an AI music talent show running entirely in your browser 🗣️🗣️</title>
      <dc:creator>Jowi A</dc:creator>
      <pubDate>Mon, 25 May 2026 06:58:44 +0000</pubDate>
      <link>https://dev.to/jowi00000/gemma4-challenge-356b</link>
      <guid>https://dev.to/jowi00000/gemma4-challenge-356b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&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%2Fbty5n2h5r66f6neia8uk.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%2Fbty5n2h5r66f6neia8uk.png" alt="Gemma - The Host" width="647" height="148"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://the-g-factor.vercel.app" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;the-g-factor.vercel.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;In psychometrics there is a beautiful, slightly controversial idea called the &lt;strong&gt;g factor&lt;/strong&gt;. The short version: across wildly different mental tasks (vocabulary, spatial puzzles, arithmetic, pattern matching) people who do well on one tend to do well on the others, and statisticians can squeeze that shared variance into a single number. One latent "general intelligence" that quietly predicts performance everywhere. 🧠&lt;/p&gt;

&lt;p&gt;I built a browser app that makes a the new Gemma 4 2B model write music, and I named it &lt;strong&gt;The G Factor&lt;/strong&gt; on purpose. Not as a cute pun (although it is one, three times over), but because the name is the whole argument I want to make: &lt;strong&gt;you do not need a giant model to look generally capable across a diverse range of tasks. You need a small model in the right harness.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The name is the thesis 🎵
&lt;/h2&gt;

&lt;p&gt;The name has 3 meanings which map onto something the app actually does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;G&lt;/strong&gt; in &lt;strong&gt;Gemma&lt;/strong&gt;, the model doing all the work, fully on your machine.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;g factor&lt;/strong&gt; of psychometrics, one capacity stretched across many different tasks.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;"Factor"&lt;/strong&gt; in &lt;em&gt;X-Factor&lt;/em&gt;, because the app is literally a talent show where you judge contestants. 🎤&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That middle meaning is the one I keep coming back to. Lay the psychometric idea next to the app and it lines up almost suspiciously well:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Psychometric &lt;strong&gt;g factor&lt;/strong&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;The G Factor&lt;/strong&gt; (the app)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One latent capacity that predicts performance across diverse tasks&lt;/td&gt;
&lt;td&gt;One small Gemma model performing across diverse musical tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A battery of varied subtests&lt;/td&gt;
&lt;td&gt;A bracket of 4 to 8 contestants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The individual subtests&lt;/td&gt;
&lt;td&gt;8 musical axes (polyrhythmic, polyphonic, modulated, timbral, harmonic, tempo-shifted, sparse, dense)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The examiner scoring each response&lt;/td&gt;
&lt;td&gt;You, judging two contestants head to head&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adapting the test to the test-taker&lt;/td&gt;
&lt;td&gt;A session taste memory that learns what you like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Is it generally capable?"&lt;/td&gt;
&lt;td&gt;"A 2B model is enough when the runtime carries the structure"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The interesting question in intelligence research was never "how big is the brain." It was "where does general capability actually come from." That is exactly the question I find myself asking about small language models, so I built a music app to chase it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is it? 🤔
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The G Factor&lt;/strong&gt; is a browser-native live-coding companion for &lt;a href="https://strudel.cc" rel="noopener noreferrer"&gt;Strudel&lt;/a&gt;. There is no server doing the thinking. Gemma 4 runs &lt;em&gt;in your tab&lt;/em&gt; on WebGPU, generates Strudel patterns, and you play them out loud!&lt;/p&gt;

&lt;p&gt;If you have not met Strudel before (neither have I before this 😅): it is a free, open-source environment for making music by writing code, and it runs entirely in the browser. You type small JavaScript-like snippets such as &lt;code&gt;s("bd hh sd hh")&lt;/code&gt; and it loops them back as a beat, rewriting the sound the instant you change the code. It is a web port of the TidalCycles live-coding tradition, and it is a great target for this experiment precisely because the "language" is compact, composable, and instantly audible: you hear a wrong note the moment it plays.&lt;/p&gt;

&lt;p&gt;There are two ways in. In the &lt;strong&gt;Rehearsal Room&lt;/strong&gt; you chat with &lt;strong&gt;Gemma&lt;/strong&gt;, a cartoon producer who rewrites the track turn by turn ("add a four-on-the-floor kick", "make the hats busier", "give it some reverb"). In the &lt;strong&gt;Talent Show&lt;/strong&gt; you drop a seed and Gemma fields a bracket of contestants, each told to explore a different musical axis, and you judge them two at a time until one is left standing. Both surfaces feed the same taste memory.&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%2Fzwdpo63iaugbvd871rer.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%2Fzwdpo63iaugbvd871rer.png" alt="A Talent Show semifinal: two Gemma-generated contestants going head to head" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is the demo. The part worth writing about is &lt;em&gt;why a 2B model can do this at all&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teaching a model a language it never saw
&lt;/h2&gt;

&lt;p&gt;Here is the catch that makes this a real problem and not a toy: Gemma 4 almost certainly never saw Strudel during training. It is a niche live-coding DSL. So how do you get reliable, &lt;em&gt;playable&lt;/em&gt; code out of a small model for a language it does not know? That's the fun part!&lt;/p&gt;

&lt;p&gt;You stop asking the model to &lt;strong&gt;know things&lt;/strong&gt;, and you let the runtime carry the structure. Three layers do that, and this is the pattern I think transfers to any small-model-on-an-unfamiliar-domain problem.&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%2Fmhroyybgxueu85lssv1c.gif" 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%2Fmhroyybgxueu85lssv1c.gif" alt="The three-layer teaching stack: static priors and session taste feed Gemma, the parser firewall guards the output" width="760" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: static priors
&lt;/h3&gt;

&lt;p&gt;A roughly 600-token system prompt that &lt;em&gt;is&lt;/em&gt; the documentation the model never read: Strudel's mini-notation operators, the common method chains, and about 10 canonical idioms. This is not fine-tuning and it is not a vector database. It is a cheat sheet pinned to the front of every request. Cheap, deterministic, and it does most of the work. Pretty simple if you ask me 🤯!&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: session taste
&lt;/h3&gt;

&lt;p&gt;Every time you like a pattern, the app writes &lt;code&gt;{seed_code, variation_code, transformation_label}&lt;/code&gt; into IndexedDB. On the next generation it scores your past likes against the current seed with a character-bigram Jaccard similarity, takes the top 3, and injects them as a labelled &lt;em&gt;"this user has previously liked..."&lt;/em&gt; block.&lt;/p&gt;

&lt;p&gt;That is the &lt;strong&gt;"learns your taste"&lt;/strong&gt; claim, and it is honest: no weights move, no GPU time, no API call. The model adapts to you the way the psychometric test adapts to the test-taker, by feeding it the right few-shot context at the right moment. Cold start works on priors alone, and the experience just gets warmer the more you use it. And when a contestant wins its bracket, that head-to-head-verified preference is exactly what gets written back into the taste memory.&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%2Fa3y1yo9bbc7bdfp6wizc.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%2Fa3y1yo9bbc7bdfp6wizc.png" alt="A crowned Talent Show champion, saved as a head-to-head-verified taste signal" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: the parser firewall
&lt;/h3&gt;

&lt;p&gt;A small model &lt;em&gt;will&lt;/em&gt; hallucinate broken syntax. So nothing it generates is trusted. Every output is parsed with &lt;code&gt;acorn&lt;/code&gt;, validated against a &lt;code&gt;zod&lt;/code&gt; schema, and walked for a deny-list of dangerous references before a single note plays. If it fails, the app retries up to 3 times with a hint that says &lt;em&gt;exactly&lt;/em&gt; what was wrong ("previous attempt was invalid because: ..."). Invalid code never reaches the UI, and unsafe code (think &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;eval&lt;/code&gt;, &lt;code&gt;localStorage&lt;/code&gt;) never reaches the audio engine. 🔒&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%2Fjd3xykcitn94zumyxzrr.gif" 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%2Fjd3xykcitn94zumyxzrr.gif" alt="The parser firewall: raw output runs through JSON parse, syntax check, and a security walk before it is allowed to play" width="720" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Priors tell the model the rules. Taste tells it your style. The firewall guarantees the output is real. None of those three layers is the model getting smarter. They are the &lt;em&gt;runtime&lt;/em&gt; getting smarter, and that is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the smallest model was the right call
&lt;/h2&gt;

&lt;p&gt;The judging rubric asks for intentional model selection, so let me be blunt about it: I picked the &lt;em&gt;smallest&lt;/em&gt; model in the family on purpose, and I would defend that choice in a heartbeat.&lt;/p&gt;

&lt;p&gt;The app uses &lt;strong&gt;Gemma 4 E2B&lt;/strong&gt; (effective 2B parameters, q4f16 ONNX). It is around 1.5 GB on disk, loads in under two minutes on a mid-range laptop, runs comfortably on WebGPU, and falls back to WASM when WebGPU is missing. After the first download it needs &lt;em&gt;zero&lt;/em&gt; network. The whole loop (generate, like, re-generate) runs offline.&lt;/p&gt;

&lt;p&gt;Could I have reached for something bigger? Sure. But once the three layers carry the structure, the model's actual job shrinks to something tiny: take a seed plus 3 stylistic exemplars and emit one short JSON object. That is well within a 2B model's reach. Spending 30 billion parameters on a task this constrained would be paying for generality I already built into the harness.&lt;/p&gt;

&lt;p&gt;I did wire in an optional cloud path too, &lt;strong&gt;Gemma 4 31B&lt;/strong&gt; via OpenRouter's free tier, for visitors without WebGPU or who want a faster bracket. Same prompts, same firewall, same axis directives. Feel free to run it both ways and watch the small local model hold its own against its much larger sibling!&lt;/p&gt;

&lt;h2&gt;
  
  
  The bigger picture
&lt;/h2&gt;

&lt;p&gt;I think we are still over-indexed on model size. The instinct, when a small model stumbles, is to reach for a bigger one. But a lot of "the model is not smart enough" is really "the runtime is not doing its share."&lt;/p&gt;

&lt;p&gt;Google does a version of this trick at scale: pre-loading, pre-fetching, doing cheap predictive work &lt;em&gt;before&lt;/em&gt; you ask so the expensive step feels instant. The same idea applies to small models. A retrieval step, a constrained output schema, a validation firewall, a handful of well-chosen few-shot examples: these are cheap pre-calls that make a 2B model behave like something far larger, and they run on a laptop with no data leaving the machine.&lt;/p&gt;

&lt;p&gt;If you take one practical thing from this post, take this: before you upgrade the model, ask what structure you can move out of the weights and into the runtime. Pin the rules. Retrieve the context. Validate the output. A small local model wrapped like that is private, offline-capable, free to run, and genuinely good enough for a surprising amount of real work. Try it on your own niche domain or DSL and I think you will be surprised how far E2B gets you.&lt;/p&gt;

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

&lt;p&gt;The whole thing is live and runs entirely client-side:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://the-g-factor.vercel.app/" rel="noopener noreferrer"&gt;https://the-g-factor.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open it in any WebGPU-capable Chromium browser. The first load pulls the weights into the HTTP cache; after that you can go fully offline and the whole loop still works.&lt;/p&gt;

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

&lt;p&gt;I had a lot of fun building this, and there were a few more things I wanted to work on: swapping the bigram similarity for small on-device embeddings so the taste memory gets sharper, and leaning harder into the "cheap pre-call" idea, doing predictive generation in the background so the next contestant is ready before you ask for it. The pre-loading vision is where I think small local models get genuinely exciting.&lt;/p&gt;

&lt;p&gt;So finally, I did not teach Gemma to write Strudel. I let the runtime teach it, and I let &lt;em&gt;you&lt;/em&gt; teach it your taste 😁&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/JowiAoun" rel="noopener noreferrer"&gt;
        JowiAoun
      &lt;/a&gt; / &lt;a href="https://github.com/JowiAoun/The-G-Factor" rel="noopener noreferrer"&gt;
        The-G-Factor
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06" rel="nofollow"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/d7955391250f6758cdf80ea20da2eed3a16af000bb41cddc5f99b9e15dd02dd0/68747470733a2f2f7468652d672d666163746f722e76657263656c2e6170702f6173736574732f696d616765732f6c6f676f2e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/d7955391250f6758cdf80ea20da2eed3a16af000bb41cddc5f99b9e15dd02dd0/68747470733a2f2f7468652d672d666163746f722e76657263656c2e6170702f6173736574732f696d616765732f6c6f676f2e706e67" alt="The G Factor" width="130"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5698772a027fc58187d39f887ea978af05ed9395f1150f8ea7e3a5cb93173cf7/68747470733a2f2f7468652d672d666163746f722e76657263656c2e6170702f6173736574732f696d616765732f67656d6d612e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/5698772a027fc58187d39f887ea978af05ed9395f1150f8ea7e3a5cb93173cf7/68747470733a2f2f7468652d672d666163746f722e76657263656c2e6170702f6173736574732f696d616765732f67656d6d612e706e67" alt="Welcome to The G Factor, with Gemma as your host for tonight"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In psychometrics there is a beautiful, slightly controversial idea called the &lt;strong&gt;g factor&lt;/strong&gt;. The short version: across wildly different mental tasks (vocabulary, spatial puzzles, arithmetic, pattern matching) people who do well on one tend to do well on the others, and statisticians can squeeze that shared variance into a single number. One latent "general intelligence" that quietly predicts performance everywhere. 🧠&lt;/p&gt;
&lt;p&gt;I built a browser app that makes a 2-billion-parameter model write music, and I named it &lt;strong&gt;The G Factor&lt;/strong&gt; on purpose. Not as a cute pun (although it is one, three times over), but because the name is the whole argument I want to make: &lt;strong&gt;you do not need a giant model to look generally capable across a diverse range of tasks. You need a small model in the right harness.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The name is the&lt;/h2&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/JowiAoun/The-G-Factor" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>From Deadlocks to Green Streaks: Building an AI Greenhouse with Gemini in 36 Hours 🧑‍🌾</title>
      <dc:creator>Jowi A</dc:creator>
      <pubDate>Tue, 03 Mar 2026 06:30:30 +0000</pubDate>
      <link>https://dev.to/jowi00000/from-deadlocks-to-green-streaks-building-an-ai-greenhouse-with-gemini-in-36-hours-15gf</link>
      <guid>https://dev.to/jowi00000/from-deadlocks-to-green-streaks-building-an-ai-greenhouse-with-gemini-in-36-hours-15gf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/mlh-built-with-google-gemini-02-25-26"&gt;Built with Google Gemini: Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://devpost.com/software/plante" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd112y698adiu2z.cloudfront.net%2Fphotos%2Fproduction%2Fsoftware_thumbnail_photos%2F004%2F173%2F371%2Fdatas%2Fmedium.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://devpost.com/software/plante" rel="noopener noreferrer" class="c-link"&gt;
            Plante | Devpost
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            We built Plante, a plant monitor, so you can touch grass inside
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
          devpost.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&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%2F9boxdeg4ddf8gdl122lo.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%2F9boxdeg4ddf8gdl122lo.png" alt="User's farm character next to his farm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built with Google Gemini
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Spark
&lt;/h3&gt;

&lt;p&gt;As university students, my teammates and I noticed a common problem: lots of people want to grow their own fruits and vegetables but simply don't have the time to monitor a garden. We wanted to bridge that gap. We set out to create a system that could teach anyone how to automatically grow their own produce using a simple, accessible Raspberry Pi kit.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Plante 🌱
&lt;/h3&gt;

&lt;p&gt;Built over 36 hours at the MLH sponsored uOttaHack 8 with almost a thousand registered students, &lt;a href="https://devpost.com/software/plante" rel="noopener noreferrer"&gt;Plante&lt;/a&gt; &lt;em&gt;(French for "plant")&lt;/em&gt; is a prize-winning mini automated greenhouse and gamified learning platform. We hooked up temperature, humidity and soil sensors to a Raspberry Pi and an Arduino, allowing the physical greenhouse to automatically open and close its hatch using servos to regulate its environment. We also added a camera to monitor the plant’s health.&lt;/p&gt;

&lt;p&gt;To make learning fun, we built a sleek, gamified frontend (which actually won "Best Design" prize!). Users earn XP, maintain "green streaks", and unlock achievements in their personal museum for keeping their plants alive. Users also can visit their friends’ farms and museums, enhancing the social aspect to growing plants!&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%2F8nz9hv9jz483j0o46e0l.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%2F8nz9hv9jz483j0o46e0l.png" alt="Kalanchoe farm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Role of Google Gemini
&lt;/h3&gt;

&lt;p&gt;As the software lead, my main focus was integrating AI to make Plante truly intelligent. I used the Google Gemini API to power two core features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context-Aware AI Chat:&lt;/strong&gt; We didn't want a generic botany bot. We passed real-time sensor data from the user's specific farms directly into the prompt context. If a user asks, "Help, my &lt;em&gt;Tomato Farm&lt;/em&gt; is critical 😭😭😭", Gemini knows exactly what the humidity and temperature levels are for that farm and provides targeted, actionable advice.&lt;br&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%2F98p1ut963unkchebbudb.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%2F98p1ut963unkchebbudb.png" alt="Chat feature"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Weekly Pulse Insights:&lt;/strong&gt; Gemini analyzes the plant's data over the week to generate custom reports and suggestions, helping users learn long-term farming habits. This goes with our goal of continuously teaching the user about their farm.&lt;br&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%2Fgye1flbzwezrgiqnxf1l.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%2Fgye1flbzwezrgiqnxf1l.png" alt="Weekly pulse report"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;You can check out our full hardware and software demo in action right here:&lt;br&gt;


  &lt;iframe src="https://www.youtube.com/embed/7n9EgHPRCC8"&gt;
  &lt;/iframe&gt;


&lt;br&gt;
&lt;em&gt;Feel free to register in the &lt;a href="https://plante-flame.vercel.app" rel="noopener noreferrer"&gt;Plante app&lt;/a&gt; directly, but beware that AI features have been disabled after the hackathon ended.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's a demo CodePen of the little farm game where you can see your farms, originally written in TypeScript from scratch 😀. Press &lt;code&gt;G&lt;/code&gt; to express yourself!&lt;/p&gt;

&lt;p&gt;

&lt;iframe height="600" src="https://codepen.io/zkttazgw-the-flexboxer/embed/JoRYVRz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;


&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Technical Skills
&lt;/h3&gt;

&lt;p&gt;Hooking up physical hardware to a web application is NO JOKE 🥶. We had to create a dedicated sensor polling service on the Raspberry Pi which our app’s server talked with because our initial approach of requesting sensor data from the app’s backend would end up causing deadlocks. So more moving parts means exponentially more thought to put into the architecture of a system. We also learned how to wire servos and sensors to an Arduino, route that through a Raspberry Pi, and expose the hardware states to our app via a REST API.&lt;/p&gt;

&lt;p&gt;With all the complexities in creating a fully featured software application with hardware and connecting them together, I would still highly recommend taking on a similar kind of challenge to anyone as it was a lot of fun. We took on this with almost no knowledge of hardware, you can do it even better! Nowadays it is extremely accessible to bridge knowledge gaps with multi-modal AI models like Gemini, allowing you to communicate with it without limits. If you would like to learn how to build apps with Google AI Studio, I would recommend following the &lt;a href="https://dev.to/deved/build-apps-with-google-ai-studio"&gt;"Build Apps with Google AI Studio" track&lt;/a&gt;. The curriculum follows a clever route to teach and make you get creative on your own.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__11026"&gt;
  &lt;a href="/googleai" class="ltag__user__link profile-image-link"&gt;
    &lt;div class="ltag__user__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%2Forganization%2Fprofile_image%2F11026%2F386b14d3-cc9a-4270-aba0-3e41cdfb9d85.jpg" alt="googleai image"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
      &lt;a href="/googleai" class="ltag__user__link"&gt;Google AI&lt;/a&gt;
      Follow
    &lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a href="/googleai" class="ltag__user__link"&gt;
        Our goal is to equip developers with the most advanced models to build new applications, helpful tools to write better and faster code, and make it easy to integrate across platforms and devices.
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;h3&gt;
  
  
  Unexpected Lessons (The Hackathon Pivot)
&lt;/h3&gt;

&lt;p&gt;Our original grand plan included a fully automated water pump. However, deep into the hackathon, we realized our hardware kit simply couldn't draw enough power to run the pump effectively 👎. With the clock ticking down, we had to triage. We completely scrapped the physical pump idea and quickly pivoted to a software solution: we wired the "Water Now" trigger to test sending mobile push notifications to the user instead. It taught us a massive lesson in MVP scoping and adapting on the fly when hardware refuses to cooperate!&lt;/p&gt;

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

&lt;p&gt;We want to take Plante even further by designing a better mechanical box to fit larger plants, adding more advanced actuators, and expanding the software features to support community leaderboards. It would be really cool to add a Raspberry Pi AI HAT+ 2 Kit to have the farm deployable on the edge with LLM/LVM capabilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Google Gemini Feedback
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Good
&lt;/h3&gt;

&lt;p&gt;We utilized Gemini 2.5 Flash, and its speed and balance of performance were incredible for a fast-paced hackathon. The massive 1 million token context window meant we could pass context (temperature, humidity, light, farms, user info) directly into the prompt without worrying about cutting data. Additionally, our team had little to no experience with hardware. When we were stuck, we took pictures of our hardware and sent it to Google Gemini through the web interface, in text and image. It was of such big help, so much so that our team’s hardware lead went on to create &lt;a href="https://devpost.com/software/product-creator-temp-name-conu-x" rel="noopener noreferrer"&gt;Buildo&lt;/a&gt; in his next hackathon, an app that turns hardware ideas into reality by generating an image with Gemini and finding the components needed to turn the idea into reality. His team went on to win MLH’s best use of Gemini API, truly showing the powers of Gemini in hardware! I truly believe Gemini is untapped for hardware, help yourself and take advantage of this. Share in the comments any tracks you recommend 😁.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Bad
&lt;/h3&gt;

&lt;p&gt;While the context window is huge, we noticed that if we didn't explicitly rein the model in with our system instructions, it occasionally had a tendency to "overengineer" its advice, jumping the gun on complex solutions rather than just answering the user's specific plant question. It required some rigorous prompt engineering and testing to keep the AI strictly within its helpful "Plante Assistant" persona without hallucinating tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Ugly
&lt;/h3&gt;

&lt;p&gt;Rate limits. The free tier limits for the Gemini API (which dropped recently to around 15 requests per minute for Flash) hit us hard during our rapid, late-night testing phases. We kept running into the dreaded &lt;code&gt;429 Too Many Requests&lt;/code&gt; error right when we were trying to debug the chat feature. We had to quickly pause our UI work to learn and implement exponential backoff logic to keep the app from crashing during our demo prep. This was fair nonetheless as we received our API key with just a few clicks and were able to use it right away 🫡.&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/JowiAoun" rel="noopener noreferrer"&gt;
        JowiAoun
      &lt;/a&gt; / &lt;a href="https://github.com/JowiAoun/Plante" rel="noopener noreferrer"&gt;
        Plante
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      We built Plante, a plant monitor, so you can touch grass inside
    &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;🌱 Plante&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🏆 Best Designed Award&lt;/strong&gt; – uOttaHack 8 2026&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A gamified, pixel-art smart plant monitoring system with AI chat, Raspberry Pi sensor integration, and real-time farm management.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://devpost.com/software/plante" rel="nofollow noopener noreferrer"&gt;Devpost&lt;/a&gt;&lt;/strong&gt; | &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=7n9EgHPRCC8" rel="nofollow noopener noreferrer"&gt;Demo Video&lt;/a&gt;&lt;/strong&gt;&lt;/p&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;🎮 Pixel-Art UI&lt;/strong&gt; – Retro-styled interface using PICO-8 color palette and NES.css&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 AI Chat Assistant&lt;/strong&gt; – Gemini-powered chat with voice synthesis (ElevenLabs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📊 Live Sensor Data&lt;/strong&gt; – Real-time temperature, humidity, and soil moisture from Raspberry Pi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📸 Pi Camera Feed&lt;/strong&gt; – Auto-capturing plant photos with pixel-art filters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔔 Smart Notifications&lt;/strong&gt; – In-app and SMS alerts via Twilio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📈 Weekly Pulse&lt;/strong&gt; – AI-generated weekly insights about your plants&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🏆 Gamification&lt;/strong&gt; – XP, levels, achievements, and leaderboards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔐 Google Auth&lt;/strong&gt; – Secure authentication with NextAuth.js&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install dependencies&lt;/span&gt;
npm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Set up environment variables&lt;/span&gt;
cp .env.example .env
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Edit .env with your API keys&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start development server&lt;/span&gt;
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/JowiAoun/Plante" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>devchallenge</category>
      <category>geminireflections</category>
      <category>gemini</category>
      <category>mlh</category>
    </item>
  </channel>
</rss>
