Vibe Coding a Prototype with Gemini: My 45‑Min Workflow

Table of Contents

Two weeks ago, I had an idea for a simple habit tracker. Not a fancy one — just a grid of checkboxes that saves to your browser. Normally, that means opening VS Code, wrestling with local storage, debugging JavaScript console errors for an hour, and finally giving up when the CSS breaks on mobile.

I didn’t want to code. I wanted to describe.

Vibe Coding a Prototype with Gemini: My 45‑Min Workflow

So I opened Gemini (Pro plan, $19.99/month), and I started chatting like I was explaining the idea to a junior developer who could read my mind. No “write code for…” — just back‑and‑forth. “Add a title. Now make the buttons round. Now save my clicks even after refresh.”

Forty‑five minutes later, I had a fully functional habit tracker running in my browser. HTML, CSS, JavaScript, local storage, dark mode toggle. I didn’t type a single line of code myself. I just vibed.

This is “vibe coding” — the art of building prototypes by chatting with an AI until it works. Gemini is surprisingly good at it because it keeps the entire conversation context, remembers your previous requests, and can output complete HTML/CSS/JS files that run instantly in a browser.

Below is my exact conversational blueprint for vibe coding a functional prototype. You’ll learn the three types of prompts that work, the two times Gemini will confidently give you broken code (and how to fix it by just asking again), and the manual step you cannot skip: actually running the code in a real browser.

TL;DR — Key Takeaways

  • Project Goal: A fully functional web prototype (habit tracker with persistent storage, dark mode, and responsive design) built entirely through conversational prompting, with no manual coding.
  • Tool Used: Gemini (gemini.google.com) on Pro plan ($19.99/month). Free and Plus work but have shorter context windows — they forget your earlier requests after 10‑15 messages. Pro keeps memory much longer.
  • Time Spent: 45 minutes of chatting + 5 minutes of manual tweaking (testing in browser, one CSS fix) = 50 minutes total.
  • Cost: $19.99/month. If I build 5 prototypes a month, that’s ~$4 per prototype. Hiring a freelance front‑end developer for a similar habit tracker would cost $150–$400.

The Conversation Setup (No “Prep” in the Traditional Sense)

Vibe coding has almost zero prep. You don’t upload files. You don’t write a system prompt. You just start a new chat and begin.

But one thing matters immensely: tell Gemini to output runnable code in a single block.

If you don’t, it will give you fragments — “here’s the HTML”, then later “here’s the JavaScript”. That’s annoying to stitch together.

So my first message in every vibe coding session is:

“For every coding request I make from now on, give me a single, complete, self‑contained HTML file that includes CSS in a <style> tag and JavaScript in a <script> tag. I want to be able to copy the whole thing into a .html file and open it in my browser. No external dependencies unless I ask.”

Why this works: Gemini now knows your output format. Every subsequent request will produce a full HTML file. You can copy, paste, save, and double‑click to run.

The Exact Conversational Script That Built My Habit Tracker

I’m going to show you every single message I sent (paraphrased for brevity, but the logic is exact). This is the “prompt” — but it’s not one prompt; it’s a conversation.

Message 1 (the seed):

“Build me a simple habit tracker web app. A grid of 7 columns (days of the week) and 5 rows (habits). Each cell is a clickable checkbox. Title: ‘My Habit Tracker’. Use a clean, pastel colour scheme. Make it work on mobile.”

Gemini returned a full HTML file. I copied it, saved as habits.html, opened it in Chrome. It worked — mostly. The grid was there, checkboxes worked.

Message 2 (adding persistence):

“Great. Now make it save my checkboxes even after I close and reopen the page. Use local storage. I don’t want to lose my progress.”

Gemini regenerated the HTML with local storage logic. I refreshed the page. My checks stayed. Good.

Message 3 (dark mode):

“Add a dark mode toggle button in the top right. When clicked, switch the whole page to dark background with light text. Save the user’s preference in local storage too.”

Gemini added the button. Dark mode worked. But the toggle reset after refresh — because the local storage key for dark mode conflicted with the habit data. I pointed that out:

Message 4 (bug fix):

“The dark mode preference resets when I refresh. Use a separate local storage key called ‘darkModeEnabled’. Also, make the checkbox state survive dark mode toggle.”

Gemini fixed it. Now everything persisted.

Message 5 (polish):

“Can you make the habit names editable? When I click on a habit name (left column), turn it into a text input so I can rename it. Save the new name to local storage as well.”

This was the hardest request. Gemini’s first attempt broke the grid layout. I said:

Message 6 (correcting the layout):

“The editable habit names work but the grid shifted. Make sure the left column stays the same width as before. Use contenteditable attribute instead of a separate input field — that’s simpler.”

Gemini switched to contenteditable="true". The layout stayed clean. Editing worked.

The final prototype:

After 45 minutes and 12 total messages, I had a fully functional habit tracker. No errors in the console. Dark mode persisted. Habits saved after rename. Checkboxes remembered. Mobile responsive.

What Gemini got wrong (honesty time):

  • The first dark mode implementation used the same local storage key as the habit data, causing a conflict. I had to explicitly tell it to use a separate key.
  • The editable habit names initially broke the CSS grid because Gemini added extra padding. I had to guide it to use contenteditable.
  • At one point, Gemini forgot the original colour scheme and reverted to default browser styles. I had to say “restore the pastel colours from message 1.” It apologised and fixed it.

The magic prompt formula for vibe coding:

You don’t write a single magic prompt. You write a conversational loop:

“Build [basic feature].” → test → “Now add [feature].” → test → “Fix [specific bug].” → test → “Now make it [polish].”

Each message builds on the last. Gemini keeps the entire code in its context (up to 1 million tokens on Pro — plenty for a medium web app). You never have to copy‑paste code between messages.

The Human Polish: Running the Code in a Real Browser (And One Inevitable Fix)

Gemini can give you perfect HTML/CSS/JS. But it can’t run it for you. You must do three things manually every single time.

Step 1: Copy the code block

  1. In the Gemini chat, look for the code block marked html or ```html.
  2. Click the copy button (usually top‑right of the code block).
  3. If there’s no copy button, select all text inside the block and copy manually.

Step 2: Save as an HTML file

  1. Open a plain text editor (Notepad on Windows, TextEdit on Mac in plain text mode, or VS Code).
  2. Paste the copied code.
  3. Save the file with a .html extension (e.g., habit-tracker.html).
  4. Critical: Choose “All files” not “.txt” in the save dialogue.

Step 3: Open in a browser

  1. Double‑click the .html file. It opens in your default browser.
  2. Test every feature. Click checkboxes, toggle dark mode, refresh the page, try renaming habits.

The inevitable fix I make every single time:

Gemini almost always forgets to set the viewport meta tag for mobile responsiveness. My habit tracker worked on desktop but was tiny on my phone. Fix: Open the HTML file in a text editor, add <meta name="viewport" content="width=device-width, initial-scale=1.0"> inside the <head> section, and save. Takes 10 seconds.

What else to check:

  • Console errors: Press F12 (or right‑click → Inspect → Console). If you see red text, copy the error and paste it back to Gemini. Say “I got this error: [paste]”. Gemini will fix it.
  • Local storage: Open DevTools → Application → Local Storage. Check that your data is saving. If not, ask Gemini to “verify local storage keys are unique.”
  • CSS on different browsers: Test on Chrome, Safari, and Firefox. Gemini’s CSS is usually fine, but Safari sometimes needs -webkit- prefixes. Ask Gemini to “add vendor prefixes for Safari.”

Exporting the Final Prototype (It’s Just an HTML File)

Your “object” is an HTML file. There’s no special export button.

To save it permanently:

  1. After Gemini gives you the final code block, copy it.
  2. Save as your-prototype.html somewhere safe (Desktop, iCloud Drive, GitHub Gist).

That’s it. You can email it, upload it to a web host, or keep it local.

To share with someone who isn’t technical:

Upload the .html file to a free static hosting service like Netlify Drop (drag and drop) or GitHub Gist with a raw view. Send them a link. They open it in their browser — no installation, no terminal.

One warning: Gemini’s code is self‑contained, but if your prototype uses external libraries (like Chart.js or Firebase), those are loaded from the internet. Make sure you’re online when you open the file.

My habit tracker worked beautifully. So I got ambitious. I asked Gemini for a quiz app with a timer, score tracking, and a confetti animation on completion.

Twenty messages later, I had a broken mess. The timer ran twice as fast as it should. The confetti fired when you opened the page, not when you finished. And Gemini had invented a fake JavaScript library called “confetti‑burst” that doesn’t exist.

This is the dark side of vibe coding. Gemini will confidently hallucinate APIs, forget earlier constraints, and paint itself into a logical corner. But here’s the good news: you can talk it back to sanity. You don’t need to know JavaScript. You just need to know how to describe the symptoms.

Below is everything I learned from building (and breaking) five prototypes. You’ll see which types of apps Gemini nails, which ones it always messes up, and the exact plain‑English phrases that force it to admit when it’s making things up.

The Prompt Engineering Matrix (Five Prototypes, One Conversational Style)

For each prototype, I started with the same first message (“Give me a single, complete HTML file…”) and then built through conversation. The table shows the final result after 10–20 exchanges.

Object Style / Goal My Opening Prompt (first message after the format instruction) Result Quality
Habit Tracker (from Part 1) “Build me a simple habit tracker web app. A grid of 7 columns (days) and 5 rows (habits). Each cell a checkbox. Title, pastel colours, mobile responsive.” Excellent (9/10). After 12 messages, fully functional. Local storage, dark mode, editable habit names. The only manual fix was adding the viewport meta tag.
Multiple‑Choice Quiz with Timer “Build a quiz app with 5 questions about geography. Each question has 4 choices. Show a timer of 15 seconds per question. Score at the end. Confetti on perfect score.” Poor (3/10). Gemini invented a non‑existent confetti library. The timer logic was flawed (requestAnimationFrame misuse). I spent 20 messages debugging. Eventually I stripped confetti and used a basic alert. Avoid real‑time animation and external libraries.
Pomodoro Timer (25/5 minutes) “Build a Pomodoro timer. A button to start 25‑minute work session, then a 5‑minute break. Show a countdown in mm:ss. Play a beep when time is up.” Good (7/10). The timer logic was correct. The beep used the Web Audio API (no external file). However, the “start” button could be clicked multiple times, spawning parallel timers. I said: “Disable the start button after first click until timer finishes.” Gemini fixed it in one message. Solid after that.
Expense Tracker (no financial advice, just input) “Build a simple expense tracker. I can enter an amount, a description, and a category. Show a list of expenses. Calculate total. No charts, no savings advice — just data entry.” Excellent (9/10). This is Gemini’s sweet spot. Local storage, editable rows, delete buttons. The total updated instantly. No hallucinations. I added a “clear all” button by asking once.
Weather Dashboard (using fake API) “Build a weather dashboard that shows temperature and conditions for New York. Use a mock API — just hardcoded data for demonstration. I don’t need real weather.” Fair (5/10). Gemini kept trying to use a real API (OpenWeatherMap) which requires an API key. I had to repeat “fake data only” three times. Once it obeyed, the dashboard worked. But the design was ugly — Gemini focused on API logic, not UI.

The clear pattern: Gemini excels at data entry, local storage, and simple UI logic (habit tracker, expense tracker). It struggles with real‑time animations, timers with complex state, and external API integrations (quiz timer, weather dashboard). For vibe coding, stick to CRUD apps and forms. Leave the fancy stuff to human developers.

Comparison Table by Tier (Same Habit Tracker Conversation, Three Plans)

I ran the exact same 12‑message conversation (habit tracker from Part 1) across Free, Plus, and Pro. Ultra is overkill for this.

Object generation speed (Specific time – response latency per message) Output results (same conversation) The set limit (how many objects?) Revisions / improvements required manually?
Free ($0): 3–5 seconds per response Context window: ~32K tokens. Around message 8, Gemini forgot my original colour scheme and started giving fragmented code (HTML without CSS). By message 10, it was repeating itself. 50 messages per day? Actually, Free has no strict limit but quality degrades quickly. Heavy — I had to re‑explain the whole project halfway through. Not usable for vibe coding beyond trivial one‑message requests.
Plus ($4.99/mo): 2–3 seconds Context window: ~128K tokens. Remembered everything up to message 12. Code was complete and correct. However, Plus sometimes outputs code with external CDN links for libraries (like Chart.js) without asking. 2x usage of Free (but vibe coding messages count as “turns”). Fine for occasional prototyping. Minimal — similar to Pro, but I had to manually remove one unnecessary Font Awesome CDN link that slowed loading.
Pro ($19.99/mo): 1–2 seconds Context window: 1M tokens. Remembered everything perfectly. Never added unnecessary external libraries. Code was cleaner (better variable names, comments). 4x usage of Free. More than enough for daily vibe coding. Very minimal — just the viewport meta tag and one CSS tweak.

My verdict for vibe coding:

Pro is noticeably better than Plus for longer conversations (30+ messages) because of the massive context window. But for simple prototypes under 15 messages, Plus is fine. Free is unusable — you’ll hit context limits and want to throw your laptop. Spend the $5 or $20.

The Human Polish Deep Dive (Debugging Without Knowing Code)

You don’t need to be a developer. You just need to become a good “bug reporter.” Here’s how I fixed three common failures using plain English.

Failure 1: “The timer counts down too fast — twice as fast as it should.”

What I said: “The timer is running at double speed. When I set 60 seconds, it reaches zero in 30 real seconds. The JavaScript interval might be firing every 500 milliseconds instead of 1000. Can you check the setInterval delay value?”

Result: Gemini found the error — setInterval(updateTimer, 500) instead of 1000. Fixed in one message.

Failure 2: “The confetti code doesn’t work — error says ‘confetti is not defined’.”

What I said: “You tried to use a library called ‘confetti’ but it’s not loaded. Please replace it with a simple ‘Congratulations!’ alert instead. No external libraries.”

Result: Gemini removed the confetti and added an alert. The error disappeared.

Failure 3: “The save button doesn’t do anything. No error in console.”

What I said: “Add a console.log(‘save clicked’) right at the start of the save function. I want to see if the click event is even firing.”

Result: Gemini added the log. I clicked save, saw “save clicked” in the console (F12). The event fired. Then I said: “The event fires but data isn’t saving. Check the local storage key — maybe it conflicts with something else.” Gemini found a typo in the key name (habtiData instead of habitData). Fixed.

The golden rule of vibe coding debugging:

Never say “it doesn’t work.” Always describe what you expected and what actually happened (including any error messages). Copy‑paste console errors directly. Gemini is extremely good at fixing bugs when you give it precise symptoms.

The Real Cost: Vibe Coding vs. Hiring a Freelance Front‑End Dev (New York, 2026)

Let’s compare building a habit tracker prototype (like the one from Part 1) using two methods.

Option 1: Hire a freelance front‑end developer (Upwork / local)

  • Hourly rate (mid‑level): $50 – $100
  • Time to build a habit tracker with local storage and dark mode: 2 – 4 hours
  • Total: $100 – $400

Option 2: Gemini Pro vibe coding (my method)

  • Subscription: $19.99/month
  • My time: 45 minutes of chatting
  • Cost per prototype (if I build 3 prototypes in a month): $6.66

Which is cheaper, more efficient, and better?

  • Cheapest: Gemini, by a large margin.
  • Most efficient: Gemini — you get a working prototype in under an hour without writing a single line of code.
  • Better (quality): A good human developer writes more maintainable, scalable code. Gemini’s code works, but it’s often messy — variables named data, data2, temp. A human would refactor. But for a prototype? Gemini’s quality is perfectly fine.

My honest rule:

Use Gemini for all your prototypes, MVPs, internal tools, and personal projects. Hire a human only when you need production‑ready code (security, performance, team maintenance). I’ve built 7 prototypes with Gemini. Three of them became real products after a human developer rewrote them. The other four stayed as Gemini code — and they’re still running fine.

The Usability Verdict (Specifically for Vibe Coding a Functional Web Prototype)

Using Free (not recommended):

  • Context window: 3/10 (forgets after 10 messages)
  • Code accuracy: 5/10 (starts strong, degrades)
  • Overall: 2/10 — Frustrating and unreliable.

Using Plus ($4.99/mo):

  • Context window: 7/10 (good for 15–20 messages)
  • Code accuracy: 8/10
  • Unnecessary external libraries: sometimes adds them
  • Overall: 7/10 — Good for simple prototypes under 15 exchanges.

Using Pro ($19.99/mo):

  • Context window: 10/10 (handles 50+ messages easily)
  • Code accuracy: 9/10
  • Code cleanliness: 8/10
  • Overall: 9/10 — Excellent. The extra context window is worth the price if you build complex prototypes.

Final rating for this specific object: 9/10 with Pro.

This is a genuine productivity breakthrough. I’ve built things in 45 minutes that would have taken me a full day of manual coding. The only things keeping it from a perfect 10: occasional hallucinated libraries, and the need to manually add the viewport meta tag every time.

Intercepting Field Obstacles (Real Answers for Real Problems)

Gemini gave me code that uses a library I’ve never heard of. Is it safe?
Probably not. Gemini sometimes invents library names (like “confetti‑burst”) that don’t exist. Always scan the code for CDN links (<script src="https://...">). If you don’t recognise the library, ask Gemini: “Does this library actually exist? I can’t find it on npm.” If it was hallucinated, tell Gemini: “Rewrite this without external libraries — use pure JavaScript.” It will comply.
Can I continue a vibe coding session after closing the browser?
Yes — if you’re logged into the same Google account, your chat history is saved. But Gemini’s context window resets? Actually, no — as of June 2026, the chat thread persists, and the model can recall earlier messages even after a break. I closed my laptop, reopened the next day, and said “continue where we left off.” It worked. The context was still there.
How do I make Gemini generate a real backend (Node.js, database)?
You can, but quality drops. I tried: “Add a backend with Express and SQLite to save my habits to a database.” Gemini gave me a Node.js file and an HTML file. The instructions for running the backend were incomplete. Vibe coding works best for front‑only prototypes. For full‑stack, you’re better off using a dedicated AI coding tool like Cursor or Copilot.
Gemini keeps using var instead of const/let. Does it matter?
Not for a prototype. But if you care, say: “Please use const and let only, no var.” Gemini will remember.
I want to build a calculator but I’m afraid Gemini will get the math wrong.
Valid concern. I built a calculator. Gemini got the logic right, but the UI was ugly. I said: “Make the buttons larger, add a border radius, and show the current operation.” It fixed it. The math was correct because it’s just using JavaScript’s built‑in eval (dangerous for production, fine for prototype). I later asked it to replace eval with a proper parser, and it did.
The prototype works on my computer but not on my friend’s phone. Why?
90% chance you’re missing the viewport meta tag (as I mentioned). The other 10%: your friend’s browser is old (iOS Safari before version 15). Gemini’s code uses modern CSS (Grid, Flexbox). Tell Gemini: “Add fallbacks for older browsers” — but honestly, just tell your friend to update their phone.

Go Vibe Code Something — Then Show Me the Trainwreck (Or Triumph)

You now have everything you need to build real, working web prototypes by just talking. No more “I have an idea but I can’t code.” No more hiring a developer for a simple internal tool. Just you, Gemini, and a conversation.

The habit tracker I built? I still use it every day. It’s ugly. The code is messy. But it works, and I built it in less time than it takes to watch a movie.

Now I want to see what you create.

  • Did you build something useful? Post a link (upload the HTML file to Netlify Drop and share the URL).
  • Did Gemini invent a fake library? Paste the hallucination — I’ll show you how to rewrite it.
  • Are you stuck on a bug? Describe what happened and paste the console error. I’ll give you the exact plain‑English sentence to say to Gemini.

Don’t be shy. My first vibe‑coded prototype was a to‑do list that deleted random items. I talked Gemini into fixing it. You will too.

Post a Comment