<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ishant gupta</title>
    <description>The latest articles on Forem by Ishant gupta (@ishantgupta).</description>
    <link>https://forem.com/ishantgupta</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%2F3903810%2F5764cbd3-17d3-4c9c-aa8e-120a5d8dcf40.webp</url>
      <title>Forem: Ishant gupta</title>
      <link>https://forem.com/ishantgupta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ishantgupta"/>
    <language>en</language>
    <item>
      <title>I Built a Space App That Gives You Real-Time Planetary Data — Powered by Gemma 4, No Backend</title>
      <dc:creator>Ishant gupta</dc:creator>
      <pubDate>Mon, 11 May 2026 18:36:34 +0000</pubDate>
      <link>https://forem.com/ishantgupta/i-built-a-space-app-that-gives-you-real-time-planetary-data-powered-by-gemma-4-no-backend-3823</link>
      <guid>https://forem.com/ishantgupta/i-built-a-space-app-that-gives-you-real-time-planetary-data-powered-by-gemma-4-no-backend-3823</guid>
      <description>&lt;h2&gt;
  
  
  I Built a Retro Space Mission Control Powered by Gemma 4 — and It Talks Like a NASA Commander 🚀
&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%2Fsoknamjxqkt9ht7ll0v6.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%2Fsoknamjxqkt9ht7ll0v6.png" alt="best" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What happens when you give an open-source AI model the keys to the solar system?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I've been obsessed with space since I was a kid. But every space app I found was either too boring (just static facts) or too complex (needs a PhD to use).&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Cosmos Explorer&lt;/strong&gt; — a retro, terminal-aesthetic space mission control center that runs entirely in the browser, powered by &lt;strong&gt;Gemma 4&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://cosmos-explorer-ishant.netlify.app/" rel="noopener noreferrer"&gt;Live Demo → cosmos-explorer-ishant.netlify.app&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
🔗 &lt;strong&gt;&lt;a href="https://github.com/ishantgupta30/cosmos-explorer" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No downloads. No installs. Just open it and feel like you're at NASA.&lt;/p&gt;
&lt;h2&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%2Fp3h7gepx9awq8zr620dl.gif" alt="Astronaut floating in space" width="220" height="124"&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  The Idea: What if space exploration felt alive?
&lt;/h2&gt;

&lt;p&gt;Static facts are boring. I wanted something that &lt;em&gt;reacted&lt;/em&gt; — that felt intelligent, cinematic, and immersive.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Gemma 4&lt;/strong&gt; came in.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding descriptions, I let Gemma 4 generate real-time mission briefings, reveal hidden planetary secrets, narrate the night sky like a planetarium, and compare worlds with the insight of an actual scientist.&lt;/p&gt;

&lt;p&gt;Gemma 4 isn't just a feature in this app. &lt;strong&gt;It's the soul of it.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What is Cosmos Explorer?
&lt;/h2&gt;

&lt;p&gt;It's a 7-in-one space dashboard built as a single HTML file:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🌍 Solar System&lt;/td&gt;
&lt;td&gt;Animated real-physics orbits, click any planet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🤖 Mission Briefings&lt;/td&gt;
&lt;td&gt;Gemma 4 generates NASA-style planet briefings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💡 Discovery Mode&lt;/td&gt;
&lt;td&gt;Gemma 4 reveals obscure scientific secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🛰️ Satellites&lt;/td&gt;
&lt;td&gt;Live mission data for Hubble, JWST, Voyager 1 &amp;amp; more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📡 ISS Tracker&lt;/td&gt;
&lt;td&gt;Real orbital physics, updates every second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔭 Sky CAM&lt;/td&gt;
&lt;td&gt;Point your camera at the sky — Gemma 4 narrates it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚖️ Planet Compare&lt;/td&gt;
&lt;td&gt;Gemma 4 analyzes any two worlds side by side&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let me walk you through each one.&lt;/p&gt;


&lt;h2&gt;
  
  
  Feature 1: The Solar System — Click a Planet, Get a Mission Briefing
&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%2Fbtvs9oxj0gmwmmawi6f7.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%2Fbtvs9oxj0gmwmmawi6f7.png" alt="Solar system view with Saturn selected and Gemma mission briefing" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The moment you click a planet, Gemma 4 kicks in. No loading spinner for 5 seconds. Just instant, cinematic text that typewriters across the screen like a real mission computer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma's output for Saturn:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TARGET ACQUIRED: SATURN. Ring system spans 282,000 km yet only 10-100 
meters thick. Density lower than water — it would float. Enceladus moon 
sprays water geysers at 1,400 km/h. Titan has liquid methane lakes. 
145 moons confirmed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't hardcoded. Gemma 4 writes this fresh every time. I just gave it a persona:&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="nf"&gt;callGemma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are a NASA mission commander. Cite specific instruments and missions 
   by exact name. Begin with TARGET ACQUIRED:. Be cinematic. 2-3 sentences maximum.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`Generate a mission briefing for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;planetName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That system prompt is doing a LOT of work. The model picks up on tone, format, and scientific precision instantly. That's the power of a 27B instruction-tuned model.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feature 2: Discovery Mode — Secrets Gemma Reveals
&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%2Flkytzsy68wqmbpmqabjz.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%2Flkytzsy68wqmbpmqabjz.png" alt="Discovery mode showing Gemma revealing a hidden fact about Saturn's rings" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every planet has a &lt;strong&gt;Discovery Mode&lt;/strong&gt; button. Press it, and Gemma 4 digs up something genuinely obscure — not the usual "Saturn has rings" stuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real output for Saturn:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;DISCOVERY: Saturn's rings are geologically young — only 10 to 100 million years old, formed when dinosaurs walked on Earth. Cassini measured ring mass and dust accumulation rates, shocking scientists who expected billion-year-old rings. The rings may disappear in 100 million years as Saturn's gravity pulls them inward.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I prompted it as a planetary scientist with access to mission data:&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are a planetary scientist revealing a genuinely obscure fact. 
 Choose something highly specific. Cite missions, instruments, or datasets. 
 2-3 sentences. Begin with "DISCOVERY: "&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I love here: Gemma 4 doesn't just recite Wikipedia. It &lt;em&gt;connects&lt;/em&gt; facts. The dinosaur comparison? That's Gemma making an analogy on its own.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feature 3: Sky CAM — Your Camera Becomes a Planetarium
&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%2Fsf0uxwjd7r7wgx560b9r.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%2Fsf0uxwjd7r7wgx560b9r.png" alt="Sky CAM view showing Orion constellation overlay with Gemma AI analysis panel" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the feature I'm most proud of.&lt;/p&gt;

&lt;p&gt;Point your device camera at the sky (or just use the direction/tilt sliders), and Sky CAM overlays constellation lines in real time. But the real magic? Hit &lt;strong&gt;"GEMMA AI ANALYSIS"&lt;/strong&gt; and watch this happen:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Turn your gaze southward, where Orion strides across the winter sky — Betelgeuse blazing with the light of a star 700 times larger than our own Sun, a red supergiant in its final cosmic act. In 2019, Betelgeuse dimmed so dramatically that astronomers worldwide predicted imminent supernova — a reminder that even celestial constants can surprise us. The ancient Egyptians saw Orion as Osiris, god of death and resurrection, his belt stars aligned with the three pyramids of Giza."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I gave Gemma 4 a very specific persona here:&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are a live planetarium narrator with deep astronomy expertise. 
 Be vivid, poetic, scientifically precise, and cinematic.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt also feeds in the current compass direction, tilt angle, and which constellations are visible. Gemma uses all of that context to write something &lt;em&gt;specific&lt;/em&gt; to what you're actually looking at.&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;128K context window&lt;/strong&gt; of Gemma 4 shines — I can pass rich contextual data and get nuanced, location-aware responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feature 4: Planet Comparison — Gemma as Data Analyst
&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%2F4bok8padlj5z65xr1e1p.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%2F4bok8padlj5z65xr1e1p.png" alt="Planet comparison tool showing Mercury vs Mars with Gemma analysis" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pick any two planets, hit ANALYZE, and Gemma 4 breaks down the comparison like a scientist explaining it to a curious friend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mercury vs Mars:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;SIZE CONTRAST: Mars is 1.4× wider than Mercury. DISTANCE: Mercury orbits at 57.9M KM from the Sun, while Mars orbits at 227.9M KM — a vast difference in solar energy received. TEMPERATURE: Mercury surface reads -180→430°C vs Mars's -125→20°C — Mercury and Mars represent extreme thermal environments.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The structured breakdown format comes entirely from the prompt. I didn't template the output — Gemma 4 just... organizes it that way when you ask it to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feature 5: The Space Q&amp;amp;A Chat
&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%2Fnlgedl8bc2x5tgelgyi6.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%2Fnlgedl8bc2x5tgelgyi6.png" alt="Space Q&amp;amp;A chat showing Gemma answering a question about the ISS" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the bottom of the Solar System view, there's a chat bar. Ask anything about space.&lt;/p&gt;

&lt;p&gt;The system prompt is simple but effective:&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are an expert space scientist. Answer questions about planets, moons, 
 satellites, black holes, and galaxies enthusiastically. Keep answers 2-4 
 sentences with specific numbers and surprising facts.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "specific numbers" instruction is key — it stops Gemma from giving vague answers and forces it to ground responses in real data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Gemma 4? The Model Selection Decision
&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%2Fgdvoovussjewdz1i5ib3.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%2Fgdvoovussjewdz1i5ib3.gif" alt="Thinking hard" width="480" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a deliberate choice, not a default.&lt;/p&gt;

&lt;p&gt;I needed a model that could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Switch personas instantly&lt;/strong&gt; — NASA commander, planetarium narrator, planetary scientist, data analyst. All in the same app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produce short, precise outputs&lt;/strong&gt; — The UI doesn't have space for essays. 2-3 sentences max.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work reliably via API&lt;/strong&gt; — The whole app runs client-side, so I needed a stable, fast endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle creative + factual tasks&lt;/strong&gt; — Mission briefings need drama. Discovery Mode needs accuracy. Both at once is hard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I went with &lt;strong&gt;&lt;code&gt;gemma-4-27b-it&lt;/code&gt;&lt;/strong&gt; (the 27B dense model via Google AI Studio's Gemini API).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why 27B and not 2B or 4B?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The smaller models are amazing for edge/mobile deployment — but they struggled with the tonal range this app demands. A 4B model would give me a decent mission briefing &lt;em&gt;or&lt;/em&gt; a poetic sky narration, but not both reliably. The 27B model handles persona-switching cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not the 26B MoE?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MoE is built for high-throughput reasoning. My use case is lots of &lt;em&gt;short&lt;/em&gt; creative + factual bursts, not long-chain reasoning. The dense 27B was the better fit here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The killer feature: instruction following&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every Gemma 4 call in this app has a very specific system prompt. The model follows them precisely — it doesn't ramble, doesn't break character, doesn't exceed the sentence limit I set. That level of instruction-following made the entire UI feel polished.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture (The Short Version)
&lt;/h2&gt;

&lt;p&gt;The entire app is &lt;strong&gt;one HTML file&lt;/strong&gt;. No frameworks, no build step, no server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cosmos Explorer
├── Canvas-based solar system (vanilla JS + requestAnimationFrame)
├── Real orbital mechanics (Kepler's equations)
├── ISS tracker (simulated TLE physics)
├── NASA images via JPL/APOD APIs
├── Space news via curated data
└── Gemma 4 via Gemini API (gemma-4-27b-it)
    ├── Mission briefings (on planet click)
    ├── Discovery Mode (on button press)
    ├── Sky CAM narration (on analyze)
    ├── Planet comparison (on analyze)
    └── Space Q&amp;amp;A (persistent chat)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gemma integration is surprisingly clean — one &lt;code&gt;callGemma()&lt;/code&gt; function that every AI feature uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;callGemma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;systemText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;350&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://generativelanguage.googleapis.com/v1beta/models/gemma-4-27b-it:generateContent?key=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;system_instruction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;systemText&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userText&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
      &lt;span class="na"&gt;generationConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maxOutputTokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;maxTokens&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Every Gemma feature in the entire app flows through that one function. Clean, simple, powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Moment That Made Me Go "Whoa"
&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%2Frzs0vzzfds0vgl2kk8bl.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%2Frzs0vzzfds0vgl2kk8bl.gif" alt="Mind blown reaction" width="350" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During testing, I clicked on Earth and asked Gemma to generate a mission briefing.&lt;/p&gt;

&lt;p&gt;It said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"TARGET ACQUIRED: EARTH. The only confirmed biosphere in the known universe. Magnetic field generated by liquid iron outer core deflects solar wind at 400 km/s. 71% surface liquid water. 8.1 billion crew members aboard. Protect at all costs."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;"8.1 billion crew members aboard. Protect at all costs."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I didn't prompt that. The model extrapolated from the NASA commander persona and added something genuinely moving. That's the difference between a language model and a &lt;em&gt;creative&lt;/em&gt; language model.&lt;/p&gt;

&lt;p&gt;That line stayed in the app.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exoplanet Explorer&lt;/strong&gt; — Gemma 4 generating habitability reports for Kepler catalog planets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mission Planner&lt;/strong&gt; — Ask Gemma to plan a hypothetical mission to any planet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Night Sky Events&lt;/strong&gt; — Gemma narrating upcoming eclipses, conjunctions, meteor showers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline mode&lt;/strong&gt; — Gemma 4 2B/4B running locally via WebGPU (no API key needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The offline idea excites me most. The 4B model is small enough to run in the browser — imagine a space education tool that works with zero internet, perfect for schools and rural areas.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;🚀 Live Demo:&lt;/strong&gt; &lt;a href="https://cosmos-explorer-ishant.netlify.app/" rel="noopener noreferrer"&gt;cosmos-explorer-ishant.netlify.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open it, click Saturn, hit Discovery Mode, then go to Sky CAM and press Gemma AI Analysis. That sequence will show you everything Gemma 4 can do in about 60 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;People talk about AI like it's a search engine replacement. But Gemma 4 did something different here — it became a &lt;em&gt;narrator&lt;/em&gt;. It gave this app a voice, a personality, a sense of drama.&lt;/p&gt;

&lt;p&gt;Space is the most dramatic story humanity has ever told. I just needed an AI good enough to tell it.&lt;/p&gt;

&lt;p&gt;Gemma 4 was that AI. 🌌&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with vanilla JS, Canvas API, and Gemma 4 via Google AI Studio.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;No frameworks were harmed in the making of this app.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Thanks for reading!!&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;#gemma4&lt;/code&gt; &lt;code&gt;#googleai&lt;/code&gt; &lt;code&gt;#javascript&lt;/code&gt; &lt;code&gt;#space&lt;/code&gt; &lt;code&gt;#webdev&lt;/code&gt; &lt;code&gt;#ai&lt;/code&gt; &lt;code&gt;#opensource&lt;/code&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>I Tried to Run Google's Most Enterprise Database on My MacBook. Here's What Actually Happened.</title>
      <dc:creator>Ishant gupta</dc:creator>
      <pubDate>Wed, 29 Apr 2026 13:57:01 +0000</pubDate>
      <link>https://forem.com/ishantgupta/i-tried-to-run-googles-most-enterprise-database-on-my-macbook-heres-what-actually-happened-36gf</link>
      <guid>https://forem.com/ishantgupta/i-tried-to-run-googles-most-enterprise-database-on-my-macbook-heres-what-actually-happened-36gf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-cloud-next-2026-04-22"&gt;Google Cloud NEXT Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At Google Cloud NEXT '26, buried inside announcement #68 of 260 total announcements, was a single sentence that stopped me cold:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Run it anywhere — across multiple clouds, on-premises, or on your laptop."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"It" is &lt;strong&gt;Google Spanner&lt;/strong&gt; — the database that powers Gmail, Google Ads, Google Pay, and YouTube. The system Walmart, Goldman Sachs, and Shopify depend on for their most critical workloads.&lt;/p&gt;

&lt;p&gt;They said I could run it on my laptop. So I tried. Here's the honest account of what happened — including the part where Google locked me out before I even started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler: Spanner Omni itself requires whitelisting. But what I could run locally surprised me more than I expected.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Spanner Omni Actually Is
&lt;/h2&gt;

&lt;p&gt;Spanner Omni is Google's answer to a question nobody thought they'd ask: what if you could take the database that runs Google's entire ad business and make it deployable anywhere — on AWS, on-premises, in an air-gapped data center, or on a developer's MacBook?&lt;/p&gt;

&lt;p&gt;The hard engineering problem wasn't the database itself. It was &lt;strong&gt;TrueTime&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Original Spanner's legendary consistency guarantees depend on atomic clocks and GPS hardware physically embedded inside Google's data centers. That hardware is what lets Spanner know, with mathematical certainty, the order in which transactions happened across data centers on opposite sides of the planet.&lt;/p&gt;

&lt;p&gt;You cannot ship GPS satellites in a Docker image.&lt;/p&gt;

&lt;p&gt;So Google built a software-defined TrueTime alternative — a reimplementation that provides error-bounded time synchronization without specialized hardware, relying on the insight that Spanner can tolerate weaker uncertainty bounds because it overlaps time-uncertainty waits with other database work.&lt;/p&gt;

&lt;p&gt;That is not a minor detail. That's a fundamental reimagining of one of distributed systems' most famous components, shipped quietly alongside 259 other announcements.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Part Google Didn't Advertise: It's Not Public Yet
&lt;/h2&gt;

&lt;p&gt;The blog post says "available today in preview." What it doesn't prominently say: the Docker image requires Google to whitelist your account before you can pull it.&lt;/p&gt;

&lt;p&gt;I found this out the hard way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull us-docker.pkg.dev/cloud-spanner-omni-preview/release/spanner-omni:2026.r1-beta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even after configuring gcloud auth, the pull failed with the same authorization error: permission denied on the registry. The preview is real, but access is controlled. If you want in, you need to contact Google directly.&lt;/p&gt;

&lt;p&gt;This is worth knowing before you block off an evening.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Can Do Right Now: The Spanner Emulator
&lt;/h2&gt;

&lt;p&gt;While Spanner Omni stays behind Google's velvet rope, there's a fully functional local Spanner environment that IS publicly available right now: the &lt;strong&gt;Cloud Spanner Emulator&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;docker pull gcr.io/cloud-spanner-emulator/emulator

docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9010:9010 &lt;span class="nt"&gt;-p&lt;/span&gt; 9020:9020 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; spanner-emulator &lt;span class="se"&gt;\&lt;/span&gt;
  gcr.io/cloud-spanner-emulator/emulator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It pulled cleanly and started in under 2 seconds:&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%2Fd2qkrp3elpfkg00onriv.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%2Fd2qkrp3elpfkg00onriv.png" alt="Docker ps showing spanner-emulator running" width="800" height="39"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure gcloud to point to your local emulator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;auth/disable_credentials &lt;span class="nb"&gt;true
&lt;/span&gt;gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;project test-project
gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;api_endpoint_overrides/spanner http://localhost:9020/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run a real query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT 'Spanner is running on my MacBook' AS message"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2F1kq9fb3xgxsigkyjm464.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%2F1kq9fb3xgxsigkyjm464.png" alt="Terminal showing Spanner is running on my MacBook" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That line printing in my terminal felt genuinely surreal. This is the same database engine that handles Google's global ad auction, running entirely offline on a MacBook Air.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benchmark: How Fast Is It Locally?
&lt;/h2&gt;

&lt;p&gt;I didn't just want to run a hello-world query. I wanted real numbers.&lt;/p&gt;

&lt;p&gt;I inserted 1,000 rows using a shell loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 1000&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;gcloud spanner rows insert &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-db &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Users &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"UserId=&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;,Name=User&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;,Email=user&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;@test.com"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2F0tafsi9802ggmvwco5db.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%2F0tafsi9802ggmvwco5db.png" alt="Insert loop running with commit timestamps" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then timed a COUNT query across all 1,000 rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT COUNT(*) FROM Users"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a LIMIT 100 fetch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM Users LIMIT 100"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2Frtt0s7wnz50mb0i1ekzp.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%2Frtt0s7wnz50mb0i1ekzp.png" alt="LIMIT 100 query returning 100 rows in 0.37 seconds" width="800" height="1613"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Result: 100 rows fetched in 0.37 seconds on a MacBook Air.&lt;/strong&gt; COUNT across 1,000 rows returned near-instantly. For a database engine designed for planet-scale distributed workloads, that's more than responsive enough for real local development.&lt;/p&gt;


&lt;h2&gt;
  
  
  ACID Transactions Working Locally
&lt;/h2&gt;

&lt;p&gt;This is Spanner's actual superpower — strong consistency across distributed nodes. I wanted to verify it works locally too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"UPDATE Users SET Name = 'Ishant Gupta' WHERE UserId = 1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-partitioned-dml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Immediately queried it back:&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%2Fvmz2gxvsi82x8pguyizw.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%2Fvmz2gxvsi82x8pguyizw.png" alt="UPDATE statement modifying 1 row" width="800" height="134"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM Users WHERE UserId = 1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2Fiowkvbqnxv6ao8o7razw.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%2Fiowkvbqnxv6ao8o7razw.png" alt="SELECT showing Ishant Gupta updated" width="800" height="130"&gt;&lt;/a&gt;&lt;br&gt;
The change was there instantly. Then I ran aggregations across all 1,000 rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud spanner databases execute-sql test-db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT COUNT(*) as TotalUsers, 
        MAX(UserId) as MaxId, MIN(UserId) as MinId 
        FROM Users"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2Fo04xmzmi8alh3vx1v240.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%2Fo04xmzmi8alh3vx1v240.png" alt="TotalUsers 1000 MaxId 1000 MinId 1" width="800" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;COUNT, MAX, MIN — all correct, all returned in under a second. This isn't a mock. It's real Spanner consistency semantics running entirely offline.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vector Search: The AI Angle
&lt;/h2&gt;

&lt;p&gt;One of the biggest NEXT '26 announcements was Spanner's support for vector search — making it viable as an AI retrieval database with no ETL pipeline needed.&lt;/p&gt;

&lt;p&gt;I created the schema locally to see if the emulator would accept it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Documents&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;DocId&lt;/span&gt; &lt;span class="n"&gt;INT64&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;Embedding&lt;/span&gt; &lt;span class="n"&gt;ARRAY&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FLOAT32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DocId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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%2Fedkcdcw6bwrmzn54kl56.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%2Fedkcdcw6bwrmzn54kl56.png" alt="Vector search schema with Documents table created" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It accepted the schema instantly. Note: actual vector similarity search queries require cloud Spanner — but designing and validating your AI data model locally before touching production is exactly the workflow Google is targeting with these announcements.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Story: Solving the Parity Problem
&lt;/h2&gt;

&lt;p&gt;Here's what I think is genuinely underreported about both the emulator and Spanner Omni:&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%2Frj4apmspjtl9o849dayr.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%2Frj4apmspjtl9o849dayr.png" alt="Spanner dev workflow: local emulator to CI/CD to production with same SQL" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before this, building on Spanner meant one of three painful options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mocking the database (fast but inaccurate)&lt;/li&gt;
&lt;li&gt;Substituting SQLite (wrong SQL dialect, wrong behavior)&lt;/li&gt;
&lt;li&gt;Pushing every change to a cloud dev environment and waiting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a local Spanner running, the queries that work in your terminal work in production. The schema you design locally is the schema you deploy. The ACID semantics you rely on locally are the semantics you get in prod.&lt;/p&gt;

&lt;p&gt;For AI applications specifically, this matters even more. Spanner now supports vector search, Spanner Graph for relationship queries, and full-text search — all in one database. You can prototype an entire AI retrieval stack locally, for free, before spending a rupee on cloud credits.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Honest Take
&lt;/h2&gt;

&lt;p&gt;Spanner Omni as announced is not what you can run today unless Google whitelists you. That gap between the blog post and actual access is worth calling out — not as a criticism, but as something every developer should know before they try.&lt;/p&gt;

&lt;p&gt;But the emulator is real, it works, and the numbers speak for themselves: 1,000 rows, 0.37 second fetches, real ACID transactions, and vector-ready schema — all running on a MacBook Air that was also playing Spotify.&lt;/p&gt;

&lt;p&gt;The 2012 Spanner paper felt like reading about infrastructure from another planet. Running &lt;code&gt;SELECT * FROM Users&lt;/code&gt; locally in 2026 means that planet is now your dev environment.&lt;/p&gt;

&lt;p&gt;If you're building anything data-intensive — especially with AI retrieval — run these two Docker commands this weekend and see how it fits your stack. I'm waiting on Spanner Omni access; when it lands, I'll write the follow-up this article deserves.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;References:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href="https://cloud.google.com/blog/products/databases/introducing-spanner-omni" rel="noopener noreferrer"&gt;Introducing Spanner Omni&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href="https://docs.cloud.google.com/spanner-omni/overview" rel="noopener noreferrer"&gt;Spanner Omni Docs&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href="https://cloud.google.com/spanner/docs/emulator" rel="noopener noreferrer"&gt;Cloud Spanner Emulator&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href="https://cloud.google.com/blog/topics/google-cloud-next/google-cloud-next-2026-wrap-up" rel="noopener noreferrer"&gt;Google Cloud NEXT '26 Announcements&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>cloudnextchallenge</category>
      <category>googlecloud</category>
    </item>
  </channel>
</rss>
