I’m Patrick Lober, and today I’m reporting on a practical developer workflow for integrating Gemini Nano‑Banana — also known as Gemini 2.5 Flash Image — into your apps. This article summarizes a hands‑on tutorial I presented for Google for Developers and walks you through the full pipeline: experimenting in AI Studio, setting up a project and API key, installing SDKs, generating and editing images in code, using multiple input images, restoring and colorizing photos, and creating conversational image‑editing experiences. I’ll also share best practices, common pitfalls, example snippets explained in plain language, and a thorough FAQ so you can get started quickly and safely.
Table of Contents
- 🧭 Quick summary — what this guide covers
- 🔎 Background and context
- 🔐 Step 1 — Experiment in AI Studio
- 🔑 Step 2 — Project setup: API keys, billing, and environment
- 🧰 Step 3 — Install SDKs and helper libraries
- 🎨 Step 4 — Generating images with NanoBanana
- ✂️ Step 5 — Editing images in code
- 🖼️ Step 6 — Working with multiple input images
- 🕰️ Step 7 — Photo restoration and colorization
- 💬 Step 8 — Conversational image editing via chat
- ✅ Step 9 — Best practices and effective prompting
- 🐍 Step 10 — Example Python walkthrough (detailed)
- 🟨 Step 11 — JavaScript integration overview
- 🐞 Step 12 — Common pitfalls and debugging
- 💡 Step 13 — Use cases and creative ideas
- 📚 Step 14 — Resources and next steps
- ❓ Frequently Asked Questions (FAQ)
- 🔚 Conclusion — my final observations
🧭 Quick summary — what this guide covers
In short, this guide is a practical, step‑by‑step developer tutorial for NanoBanana (Gemini 2.5 Flash Image). You’ll learn how to:
- Experiment with NanoBanana in Google AI Studio for rapid prototyping.
- Configure a Google Cloud project, create an API key, and set up billing.
- Install the official Google generative AI SDK and helper libraries.
- Generate photorealistic images from prompts and edit existing images programmatically.
- Combine multiple input images for compositing tasks (for example, place a t‑shirt on a person).
- Restore and colorize old photos with a simple prompt.
- Build conversational image editing using a chat session API to iterate on results.
- Follow best practices for prompting and production usage.
🔎 Background and context
Gemini Nano‑Banana is a focused image model in the Gemini family optimized for image generation and editing. In the developer walkthrough I presented, I demonstrate how to go from exploration in AI Studio to using the Gemini developer APIs in production code. The tools used are the Google generative AI SDKs (examples for Python and JavaScript are available), along with standard image libraries such as Pillow for Python.
🔐 Step 1 — Experiment in AI Studio
If you’re new to the model, the fastest way to see what it does is through AI Studio. I always recommend starting there before writing code because the Studio is a playground: it lets you try prompts, upload and edit images, and iterate on outputs in an interactive UI. The workflow I use begins in AI Studio so I can prototype prompts and image edits quickly, then move to code once I understand how to frame the request.
Why AI Studio first?
- Fast feedback loop for prompt engineering — tweak prompts and see results instantly.
- Built‑in model picker — make sure you select NanoBanana / Gemini 2.5 Flash Image when experimenting.
- Support for uploading images and iterative editing — you can test multi‑step edits before automating them.
What to try in AI Studio
- Create from scratch: enter a prompt such as “create a photorealistic image of an orange cat with green eyes sitting on a couch” and click Run.
- Edit an upload: upload a scanned old photograph and try “restore and colorize this image.”
- Conversational edits: upload an image, then keep adding new edits in the chat-like interface to refine details.
Pro tip: while in AI Studio, you can copy the up‑to‑date model ID for use in code — this helps avoid hard‑coding preview model names that may change over time.
🔑 Step 2 — Project setup: API keys, billing, and environment
Once you have a feel for prompts and edits, it’s time to build. The two essentials are an API key and billing. NanoBanana’s image API is a paid service, and the developer experience requires a valid key tied to a Google Cloud project with billing enabled.
Step-by-step setup
- Go to AI Studio and click “Get API key.”
- Click “Create API key” and either let AI Studio create a new Google Cloud project for you or select an existing one.
- Copy the API key and store it securely — this key will authorize requests to the Gemini developer API.
- Click “Set up billing” and follow the prompts to attach a billing account to your project. Note: NanoBanana costs money per image; at the time I prepared this guide, it was approximately $0.04 per image (roughly 25 images per $1). Always check the official pricing page for up‑to‑date numbers.
- On your development machine, store the key in an environment variable — for example, create a .env file with GEMINI_API_KEY=
. This prevents hardcoding secrets in source control.
Security tip: never commit your API key to Git or other version control. Use environment variables or secret managers for production deployments.
🧰 Step 3 — Install SDKs and helper libraries
I build example code primarily in Python, but JavaScript examples are also available. For Python, install the official Google generative AI SDK and a few helper libraries:
- google‑genai — the official SDK to interact with Gemini models and other generative AI endpoints.
- Pillow — the widely used image library for reading, manipulating, and saving images.
- python-dotenv — optional helper to load environment variables from a .env file during local development.
Example install command I use:
pip install -U google-genai pillow python-dotenv
After installation, load your environment variables at runtime (if you used a .env file) so the SDK can find GEMINI_API_KEY. The SDK can also accept a key directly if you choose to pass it in code, but environment variables are safer for most workflows.
🎨 Step 4 — Generating images with NanoBanana
Let’s generate an image programmatically. The call pattern is straightforward: create a client instance from the SDK, pass the model ID, and provide the prompt(s). NanoBanana returns a mixture of text and binary outputs (image bytes). My example walks through how to detect inline binary data, convert it into an in‑memory bytes buffer, and save it as a PNG using Pillow.
How the model call looks conceptually
In my Python example, I set up a client and then call a generate function on the client’s models resource. The payload includes the model name (for example: Gemini 2.5 Flash Image preview — but prefer to copy the current model ID from AI Studio to stay up to date) and a prompt string describing the image you want.
Example prompt and behavior
“Create a photorealistic image of an orange cat with green eyes sitting on a couch.”
When you send that prompt, NanoBanana returns a list of parts. Some parts may be text (e.g., metadata, captions), while other parts are inline binary data representing the image. My code checks each part: if it’s a text part, print it; if it’s image bytes, wrap them in a bytes buffer, create a Pillow Image and save as PNG.
Output handling
- Expect one or more images (or none if something went wrong) — iterate over returned parts.
- Convert bytes to an image in memory and save to disk or pass into your application UI.
- Consider additional validations: image size, format, and DLP checks depending on your app’s safety requirements.
Pro tip: don’t hardcode a fixed model string; copy the model ID from AI Studio. Model names or preview tags can change over time; copying the ID helps avoid stale references.
✂️ Step 5 — Editing images in code
NanoBanana supports image editing, and integrating that into code requires only minor changes from the generation flow. Instead of a pure text prompt, your request contains a list of content parts: the prompt and one or more image inputs. The SDK accepts a mixed list for the contents argument where elements can be text or image objects.
How to prepare an image edit request
- Load your source image using Pillow (Image.open).
- Create a prompt that references the image, e.g., “Using the image of the cat, create a street‑level view of the cat walking in New York City.”
- Add the image object to the contents list in your model call alongside the prompt text.
- Run the request and save the returned image bytes to disk.
It’s that simple. The model uses the provided image as the primary content to transform, guided by the prompt. This flow scales to multiple turns and works well for compositing, style transfer, and contextual edits.
Practical example explained
In my demo I edited a previously generated orange cat image. The prompt explicitly used the uploaded image for context and requested a change in scene: street‑level view in New York City. The model produced a realistic edit that placed the same cat into a city street scene while preserving visual consistency with the original photograph.
🖼️ Step 6 — Working with multiple input images
NanoBanana also handles multiple input images at once, which unlocks a lot of useful scenarios: dressing a person with a shirt from another photo, compositing objects, swapping textures, or combining elements from multiple references.
How to structure a multi-image request
The contents argument becomes an ordered list of items. A typical arrangement is:
- Primary prompt (text) that explains the intended edit and constraints (e.g., “Make the girl wear this t‑shirt, leave the background unchanged”).
- Image A: the subject to be edited (e.g., a photo of the girl).
- Image B: the reference or item to transplant (e.g., a t‑shirt photo).
The model interprets this set and performs the requested editing operation. In my demonstration, the model placed the t‑shirt onto the person and carefully preserved the original background — one of NanoBanana’s strengths is maintaining unrelated context while applying edit operations.
Tips for reliable multi-image editing
- Be explicit in the prompt about which image is the target and which are references.
- Specify constraints such as “keep background unchanged” or “match the lighting” to guide the model.
- If results are inconsistent, iterate with more step‑by‑step prompts: first align the garment, then fix size, then match fabric texture.
🕰️ Step 7 — Photo restoration and colorization
Restoring and colorizing old photographs is a practical and popular use case. NanoBanana can restore damaged areas, remove noise, and colorize monochrome images with a single carefully worded prompt.
Simple prompt pattern
“Restore and colorize this image.”
Adding context helps: mention the era of the photo or specific cues such as clothing, environment, or expected colors to get more historically plausible results. For a 1932 photograph, note that in your prompt: “This is a photograph from 1932 — restore and colorize with period-appropriate colors.”
Why this works well
- NanoBanana applies inpainting and style reconstruction techniques to damaged or low‑resolution areas.
- Colorization is informed by typical color semantics learned from data; you can steer the palette by naming colors for certain objects.
Example outcome: the model restored an old portrait and produced a natural color photograph with balanced tones and lighting while preserving facial details. This use case is striking and often yields emotionally resonant outputs when restoring family photos.
💬 Step 8 — Conversational image editing via chat
One of my favorite patterns is to use a chat session to perform turn‑based or conversational image editing. Instead of doing single, one‑off generation calls, you open a chat session object in the SDK and send messages that include images and follow‑up prompts. The session keeps track of history so the model can reference previous edits and maintain continuity across turns.
How chat-based editing works
- Create a chat session: client.chats.create(model=MODEL_ID).
- Send a first message with an image and an instruction, e.g., “Change the cat to a Bengal cat.”
- Receive the edited image and show it in your UI or save it.
- Send subsequent messages for incremental edits, like “Now add a funny party hat,” or “Make the background a birthday party scene.”
- Continue the loop until you reach the desired result.
Benefits of conversational editing
- Fast iteration: each turn builds on the previous one and is easier to reason about than a single complex prompt.
- Better UX: users can make natural language requests and see immediate visual feedback.
- Stateful context: the model remembers prior edits, reducing the need to repeat constraints every time.
Example flow I demonstrate includes: original cat → Bengal cat → Bengal cat with a party hat. Each turn modifies the image while keeping consistency with prior modifications.
✅ Step 9 — Best practices and effective prompting
Prompt engineering matters. I shared several heuristics that help get better and more reliable results from NanoBanana:
Be specific; provide context and intent
Vague prompts lead to vague results. Tell the model what you want and why. Instead of “change the scene,” say “using the provided image of a cat, create a street-level, photorealistic view showing the cat walking in New York City during the daytime, with realistic shadows and buildings in the background.”
Iterate and refine
Start with a broad pass to get a general result, then refine. Use chat sessions to correct or tune details in subsequent turns. Break down complex edits into smaller steps: place the subject, then adjust lighting, then tweak clothes or accessories.
Use step-by-step instructions for complex tasks
For compositing or multi-step edits, give the model an ordered set of tasks so it knows what to prioritize. For example: “1) Replace the background with a beach. 2) Adjust shadows to match midday sun. 3) Keep the subject’s pose unchanged and retain existing facial details.”
Positive framing
Negative constraints (like “no cars”) sometimes produce ambiguous results. Instead, describe the desired state: “an empty, deserted street” is clearer than “no cars.” Positive framing helps the model aim for a target rather than avoid an unspecified set of things.
Control camera and style cues
Include photographic terms to guide the framing and lens characteristics: wide angle shot, macro shot, close-up, depth of field, bokeh, low-angle shot, overhead shot. For style and filmic cues, you can say “Kodak Portra color grading” or “cinematic lighting.”
Safety and policy checks
Before deploying, consider automating content moderation and safety checks on generated images (for example, for hateful content, sexually explicit imagery, or realistic deepfakes). Add a human review workflow for sensitive outputs and incorporate DLP or policy compliance checks if needed.
🐍 Step 10 — Example Python walkthrough (detailed)
Below I walk through the Python example I used in the demo, in plain language. This isn’t the code verbatim but a high-level explanation so you can recreate it safely in your own project.
Environment and imports
1) Load environment variables so the SDK finds GEMINI_API_KEY. 2) Import the Google generative AI client from the SDK. 3) Import Pillow’s Image class and io.BytesIO for in‑memory byte handling.
Client setup
Create a client instance using the SDK. You can optionally pass the API key into the client, but the preferred method is to set GEMINI_API_KEY as an environment variable and let the SDK pick it up automatically for security.
Single-image generation
- Define a prompt string: "create a photorealistic image of an orange cat with green eyes sitting on a couch."
- Call client.models.generate_content or equivalent, supplying the model ID and the prompt wrapped in a contents list.
- The API returns a structure containing parts; iterate over parts. For text parts, print or log them. For binary image parts, wrap the bytes in BytesIO and open with Pillow to save as PNG.
- Save to a filename like cat1.png.
Editing a loaded image
- Use Pillow to open an existing image, e.g., Image.open("cat1.png").
- Create a new prompt that references the image: "using the image of the cat create a street level view of the cat walking in New York City..."
- Supply a contents array that contains the prompt text and the image object. The SDK will send the image bytes and prompt to the model.
- Handle the returned image bytes and save as cat2.png.
Multiple inputs example
- Open the target image and the reference image (e.g., t_shirt.png).
- Compose a prompt: “Make the girl wear this t‑shirt, leave the background unchanged.”
- Pass [prompt, girl_image, tshirt_image] to the model call and save the returned result.
Conversational editing example
- Create a chat session: chat = client.chats.create(model=MODEL_ID).
- Send the initial message with the original image and instruction: chat.send_message(text="Change the cat to a Bengal cat", image=original_cat).
- Display or save the result. Then send another instruction against the same chat: chat.send_message(text="Now add a funny party hat").
- The model will maintain context and apply subsequent edits to the last image or context, producing a new image for each step.
Note: In real code, you’ll need robust error handling and retry logic for intermittent network or model errors. Add logging and monitor API usage to stay within budget and detect anomalies.
🟨 Step 11 — JavaScript integration overview
If you prefer JavaScript/TypeScript for front‑end or serverless backends, similar patterns apply: install the Google generative AI JS SDK, authenticate via environment variables or secret manager, and call the same model endpoints. JavaScript examples are available in the resources I referenced; the conceptual flow mirrors the Python examples.
Key JavaScript notes
- Use secure server-side endpoints to keep API keys hidden. Avoid calling the generative API directly from client code unless you use a short‑lived key or proxy.
- Handle image data as ArrayBuffers or Blobs in JS. Convert to/from base64 when necessary to send images in requests or receive them in responses.
- For streaming or incremental updates, consider using server-sent events or WebSockets to deliver generated images progressively to a browser UI.
🐞 Step 12 — Common pitfalls and debugging
As you build, you might run into a few common issues. Here’s what I’ve seen and how I recommend resolving them:
1. Incorrect or stale model ID
Problem: Using an outdated model string causes failures or suboptimal results. Solution: Always copy the model ID from AI Studio after selecting the model. Avoid relying on preview tags in code that might change.
2. Missing or invalid API key
Problem: Requests fail due to authentication errors. Solution: Verify GEMINI_API_KEY in your environment and never check it into source control. For server deployments, use a secret manager or environment variable configuration in your cloud provider.
3. Billing not set up
Problem: The API returns billing or quota errors. Solution: Confirm billing is attached to the project used by your API key in Google Cloud Console. Monitor usage and set alerts or quotas to avoid unexpected charges.
4. Unexpected output styles
Problem: Generated images don’t match the intended style. Solution: Improve prompt specificity, add style and camera descriptors, or use stepwise editing to converge on the desired result.
5. Large or malformed image inputs
Problem: Very large images cause timeouts or failures. Solution: Preprocess inputs: resize, crop, or compress images to reasonable sizes before sending them. Document any model input limits and abide by them.
6. Safety and policy issues
Problem: Model returns disallowed or harmful content. Solution: Add moderation checks, human review for sensitive content, and enforce policies that match your use case and legal constraints.
💡 Step 13 — Use cases and creative ideas
NanoBanana’s strengths in photorealistic generation and editing unlock a wide set of use cases across industries:
Commercial and consumer:
- On‑demand product mockups — apply clothing textures to different body types or preview furniture in rooms.
- Photo restoration for genealogy and heritage services — restore and colorize family photos.
- Social apps — let users dress up avatars or edit photos through conversational UIs.
Design and creative:
- Concept art prototyping — quickly generate photorealistic variations for scenes or characters.
- Advertising mockups — place products in location shots with accurate lighting.
Education and research:
- Historical image reconstruction for museums or archival projects.
- Visual aids or illustrations in journalism and storytelling.
In every application, consider ethics: be transparent when images were generated, avoid realistic deepfakes of identifiable people without consent, and follow relevant legal and policy requirements.
📚 Step 14 — Resources and next steps
If you want to go deeper, I compiled and referenced several resources during the tutorial that you should bookmark:
- Blog post: How to build with NanoBanana — a complete developer tutorial with code snippets and links.
- AI Studio: The prototyping playground where you can test models and copy model IDs.
- JavaScript code examples — a GitHub repo containing JS/TS examples for common flows.
- NanoBanana Hackathon — community events and challenges that showcase creative uses of the model.
- Prompting guide — an in‑depth guide authored by colleagues that covers prompting strategies and examples.
For convenience, I put the Python and JavaScript code examples in a GitHub repository and linked them from my blog post. Use those examples as starting points and adapt them to your app architecture and safety requirements.
❓ Frequently Asked Questions (FAQ)
Q: What is Gemini Nano‑Banana (Gemini 2.5 Flash Image)?
A: Gemini Nano‑Banana (also called Gemini 2.5 Flash Image) is a specialized image generation and editing model in the Gemini family. It supports photorealistic image creation, complex edits using provided images, multi‑image composition, and conversational/turn‑based editing via chat sessions.
Q: How do I start experimenting with NanoBanana?
A: Start in AI Studio. Select the NanoBanana/Gemini 2.5 Flash Image model in the model picker, then try generation and image uploads. AI Studio is the fastest way to prototype prompts and see what the model can do before writing code.
Q: What SDKs are supported?
A: Official Google generative AI SDKs support Python and JavaScript. I demonstrated a Python flow using google‑genai, Pillow for image handling, and python-dotenv for environment variable loading. JavaScript examples are available via the linked repo and can be used on server or client layers with appropriate security.
Q: How much does it cost?
A: Costs vary by model and change over time. At the time of the tutorial, the image API was approximately $0.04 per image (about 25 images per $1). Always check the official pricing page for the latest information and set quotas in Google Cloud to control spending.
Q: How do I pass images to the API?
A: The SDK accepts a contents list where each element can be text or image content. For images, load them using Pillow (or buffer them in JS) and include them in the request. The model uses these images as inputs for editing or composition based on your prompt.
Q: Can I do multi-step or conversational edits?
A: Yes. Use the chat session helper in the SDK: create a chat session, send messages with images and instructions, receive edited images, and iterate. This mirrors the interactive experience you get in AI Studio and provides a natural UX for end users.
Q: How do I make edits preserve certain parts of the image?
A: State your constraints clearly in the prompt, like “leave background unchanged” or “keep facial features identical.” If needed, break the edit into steps: first replace the object, then refine the edges and color match. If results are inconsistent, try more explicit instructions and additional contextual images.
Q: Are there limits on image resolution or file size?
A: There are practical limits. Very large images may cause timeouts or failures. Preprocess inputs as needed by resizing, cropping, or compressing. Check the SDK or API docs for any model-specific input limits and recommended image sizes.
Q: How do I handle moderation and policy compliance?
A: Before deploying, integrate moderation checks and safety filters. Use automated detectors for explicit content, hateful imagery, or other policy-sensitive outputs. Add a human-in-the-loop review for high-risk scenarios. Follow applicable laws and platform policies about synthetic content and representation of real people.
Q: Where can I find code examples?
A: I included Python and JavaScript examples in my blog post and GitHub repository. Use those as starting points and adapt them to your architecture. Remember to secure your API key and implement retries and error handling for production usage.
🔚 Conclusion — my final observations
Using Gemini Nano‑Banana is an exciting and practical way to add advanced image generation and editing to your applications. Start with AI Studio to prototype, copy the up‑to‑date model ID, create an API key with billing attached, and then integrate using the Google generative AI SDK. Whether you’re generating photorealistic images from scratch, editing existing photos, combining multiple references, restoring historical photographs, or building a conversational editing UI, the steps are approachable and the results are compelling.
I’ve shared step-by-step patterns, example flows, and best practices to help you move from experimentation to production with confidence. Try the sample prompts, iterate with chat sessions, and keep refining prompts to achieve your desired result. Above all, prioritize safety, transparency, and user consent if you plan to work with images of real people.
Have fun building — I’m excited to see what creative applications you ship with NanoBanana.



