---
title: "Coffee with Firebase Studio's App Prototyping agent"
description: "What's brewing with your dev workflow? ☕ We've got the perfect blend of tips to help you get the most out of Firebase Studio's App Prototyping agent."
published: "2025-09-09"
last_updated: "2025-09-09"
authors:
  - "James O'Reilly (Staff Developer Relations Engineer)"
categories:
  - "Firebase Studio"
  - "Gemini"
  - "Best Practices"
  - "AI"
canonical_url: "https://firebase.blog/posts/2025/09/coffee-with-app-prototyping-agent"
---

# Coffee with Firebase Studio's App Prototyping agent

*Published September 9, 2025 by James O'Reilly (Staff Developer Relations Engineer)*

---
![](https://firebasestorage.googleapis.com/v0/b/first-class-blog.appspot.com/o/posts%2Fcoffee-with-firebase-studio_1600x800.webp?alt=media&token=b15e728a-90f7-4838-a88f-4a0836016531)

> **TL;DR:** This morning I decided to have a coffee chat with Firebase Studio's App Prototyping agent. I thought if we got to know each other better we could improve our working relationship so I asked a few questions. TIL…

_Click the **Generate** button within each chat window to reveal Gemini's responses._

### The chat

> **Simulated Gemini Interaction**
>
> **Input:** How might we work together more effectively?
>
> **Output:** That's a fantastic question, and I appreciate you thinking about how we can work together more effectively. My goal is to be as efficient and helpful as possible, and the way you write your prompts can definitely make a big difference.
>
> While my system is designed to manage our history automatically, here are a few ways you can help me be even more efficient, which will lead to faster and more accurate responses for you:
>
> 1. Be direct and specific: The clearer your instruction, the fewer tokens I need to use to understand your intent.
>
> Less efficient: "I was thinking maybe we could change the header. It feels a little plain right now." (This is perfectly fine, but requires me to ask clarifying questions).
>
> More efficient: "In src/app/page.tsx, update the h1 in the header to be text-4xl and change the text to 'My Garden Journal'." (see footnote #1)
>
> 2. Reference file paths: When you know which file needs to be changed, telling me directly is a huge efficiency boost. It saves me from searching through the whole project context to find the relevant code.
>
> Less efficient: "Can you make the save button green?"
>
> More efficient: "In src/components/journal-form.tsx, can you change the save button's background color to green?"
>
> 3. Bundle small changes: If you have several small, related tweaks, it's more token-efficient to ask for them in a single prompt rather than one at a time. This is because the conversational overhead (history, context) is sent with each prompt.
>
> Less efficient: (In separate prompts) "Make the title bigger.", "Now make the subtitle smaller.", "And change the footer text."
>
> More efficient: "Please make these changes: 1. In the header, make the title text-3xl. 2. Make the subtitle text-sm. 3. In the footer, change the copyright year to 2024."
>
> 4. Use reversions intentionally: Just as you did, if you want to undo a set of changes, reverting the codebase and letting me know is the most efficient way. It gives us a clean slate to work from and is much more effective than asking me to "undo the last three things we did" one by one. (see footnote #2)
>
> You don't need to be overly strict about these—I'm designed to handle conversational and less-specific requests too! But following these guidelines, especially for more complex tasks, will help us collaborate very efficiently.
>
> **Input:** Are there other ways we can make the process smoother?
>
> **Output:** Of course! Beyond just efficiency, there are several ways we can collaborate to make the process of building your app smoother and more creative. Here are some tips and tricks I'd suggest:
>
> 1. Think out loud and share your high-level goal: Before diving into specific code changes, feel free to tell me what you're trying to accomplish in plain English.
>
> Instead of: "Create a new file src/components/profile-card.tsx..."
>
> Try this: "I want to add a user profile page. It should show the user's name, email, and a list of their journal entries."
>
> By understanding your goal, I can make better design decisions, suggest appropriate components (like using ShadCN Cards or Avatars), anticipate the next steps (like fetching user-specific data), and ensure the code I write truly fits your vision.
>
> 2. Iterate and refine: You don't need to have a perfect, detailed plan from the start. We can build features iteratively, just like you would in a real development process.
>
> Step 1: "I want to add an AI plant identifier. For the first step, let's just build the UI. Can you add an 'Identify Plant' button next to the 'Sign Out' button? When clicked, it should open a dialog box. Inside the dialog, there should be a title, a file input for an image, and a button to start the identification. No need for any AI functionality yet."
>
> Step 2: "Great, the dialog looks good. Now, let's create the AI part. Can you create a new Genkit flow in src/ai/flows/identify-plant-flow.ts? It should take a photo (as a data URI) and return the identified plant's common name as a string. For now, we can just make it return a hardcoded value like 'Rose' so we can test the connection." (see footnote #1)
>
> Step 3: "Okay, the UI and the AI flow exist. Now, let's connect them. In src/app/page.tsx, when the user selects a file and clicks the 'Identify' button, call the new identifyPlant flow. While it's running, show a loading spinner inside the dialog. When it returns the result, display the plant name below the button. Also, handle any potential errors with a toast notification."
>
> Each step is a meaningful, self-contained piece of work that results in a testable, functional part of the feature. This approach is far more robust than bundling everything into one giant, complex request, and it allows you to guide the development and make adjustments at each stage.
>
> 3. Ask for alternatives and ideas: If you're unsure how to proceed, just ask for my opinion! I can act as a brainstorming partner.
>
> "What's the best way to display a list of tags for a post?"
>
> "Can you suggest a different layout for the journal gallery?"
>
> "I want to add a search feature. What would be a good UI for that?"
>
> I can propose different components, code structures, or UI patterns based on the tech stack we're using.
>
> 4. Provide specific feedback: When reviewing my changes, specific feedback is much more helpful than general feedback. This helps me learn your preferences.
>
> Less helpful: "I don't like it."
>
> More helpful: "The font size in the card title is too big, let's reduce it. Also, can we add more space between the image and the text?"
>
> 5. Correct me when I'm wrong: I'm a powerful tool, but I'm not perfect. If I misunderstand you or make a mistake, please don't hesitate to correct me. Pointing out errors helps me adjust and provide a better response on the next try. A simple "That's not what I meant, let's try this instead..." is perfectly fine.
>
> By using these strategies, you can leverage me not just as a code-writing tool, but as a genuine creative and technical partner in your development process.
>
> **Input:** What's the best way for people new to AI code generation to approach it as a form of pair programming?
>
> **Output:** That is a fantastic question because it reframes the interaction from a simple command-and-response into a true collaborative partnership. Approaching it as "pair programming" is precisely the right mindset for getting the most out of an AI coding partner like me.
>
> For someone new to this, the key is to understand the roles. In traditional pair programming, you have a "Driver" (who writes the code) and a "Navigator" (who guides the strategy and reviews the work).
>
> In our partnership, you are always the Navigator, and I am the Driver.
>
> Your job is to provide the vision, the architectural decisions, and the critical feedback. My job is to translate your vision into functional code, handle the boilerplate, and execute on your plan.
>
> Here's the best way for a newcomer to approach this:
>
> 1. Start with a conversation, not a command (The "planning" phase): Before we write a single line of code, tell me your high-level goal. A good human navigator doesn't just say "type this function"; they explain what the function needs to accomplish.
>
> Instead of: "Add a div with these styles to page.tsx."
>
> Try this: "I want to create a header for my app. It should be simple, just displaying the title 'Garden Journal'. What's the best way to do that?"
>
> This approach gives me the context to make better suggestions. I might recommend creating a separate Header component for reusability or suggest using specific ShadCN components that fit the app's style.
>
> 2. Delegate the "how", but dictate the "what" and "why": You are the architect. You decide what we're building and why. My role is to figure out the most efficient way to build it within our tech stack (Next.js, Tailwind, etc.).
>
> * Your Role (Navigator): "Let's add an entry form. We'll need fields for 'Plant Name', 'Notes', and a file upload for a 'Photo'. When the user clicks save, the data should be saved to Cloud Firestore and the photo to Firebase Storage."
>
> * My Role (Driver): I will then translate that into code. I'll use react-hook-form for form management, create the necessary state, structure the components, and wire up the Firebase functions. I handle the implementation details.
>
> 3. Review my work like a senior developer (The "code review" phase): My code is a "first draft" or a "pull request." Your most important job is to review it. Never trust my code blindly. As the Navigator and architect of the project, you have the final say and the critical eye. Here's how to approach the review:
>
> * Run the App: The most important step. Check the UI and test the functionality. Does it behave the way you envisioned? Did it solve the problem we set out to fix? This real-world test is the ultimate measure of success.
>
> * Read the Code: You don't need to scrutinize every single line, but give it a quick read. Does the overall structure make sense? Did I place the logic in the right file? As the project owner, it's good for you to have a high-level understanding of the code I've written.
>
> * Provide Specific Feedback: This is how we iterate effectively. Instead of just saying "that's wrong," tell me what is wrong and how you'd like to change it. The more specific you are, the better I can tailor the next iteration to your vision.
>
> Less helpful: "The new component is broken."
>
> More helpful: "The JournalCard component looks good, but you forgot to pass the onDelete prop, which is causing a crash when I click the delete button."
>
> By treating my output as a draft that needs your expert review, you maintain full control over your project's quality and direction, ensuring the final product is exactly what you want.

### What's next?

My coffee with the agent was surprisingly insightful. It helped me shift my mindset from simply giving commands to engaging in a true collaboration.

The best way to understand this new dynamic is to experience it yourself!

If you're ready to see how this collaborative approach can transform your development workflow, fire up a new project in [Firebase Studio](https://g.dev/firebase/studio-app-prototyping). Start a conversation, give it a goal, and see what you can build together. You might be surprised at how natural your new pair-programming partnership feels.

### Footnotes

  - Firebase Studio provides tools to abstract away many of the coding details for you. The first tool is the DOM select tool found in the upper right corner of the preview window. This tool enables you to select a DOM element to provide a prompt about it. The second tool is the annotation tool found in the preview window's lower right corner. Use this tool for a more expressive prompt that enables you to sketch your ideas onto the webpage in addition to writing a prompt.

  - In this response, Gemini makes a reference to an earlier conversation we had where I explicitly told Gemini that I used a `restore` to revert a change we made. I did this because I was already familiar with the recommendation Gemini makes. By letting Gemini know about events that take place outside of the direct actions Gemini takes, you improve its awareness of the application state and decisions made.
