Gemini 3 and Nano Banana Image Generation with TypeScript

· combray's blog


Gemini 3 and Nano Banana Image Generation with TypeScript #

Summary #

Google launched Gemini 3 on November 18, 2025, representing their most advanced AI model to date. Alongside it, they released Nano Banana Pro (gemini-3-pro-image-preview), a state-of-the-art image generation model built on Gemini 3 Pro's reasoning capabilities. Both are accessible via the unified @google/genai TypeScript SDK.

Gemini 3 Pro achieved a record 1501 Elo on LMArena, becoming the first model to surpass the 1500-point threshold. The model excels at complex reasoning, multimodal understanding, and agentic coding tasks. Nano Banana Pro builds on this foundation to provide industry-leading image generation with superior text rendering, multi-image composition, and 4K output support.

For TypeScript developers, the recommended approach is using the @google/genai package (v1.30.0+), which provides unified access to all Gemini models including text generation, image generation, and multimodal capabilities. The legacy @google/generative-ai package is deprecated and will lose support by November 30, 2025.

Project Context #

This project is a new Node.js TypeScript setup. The mise.toml configuration indicates Node.js latest is the target runtime. The recommendations below are tailored for a greenfield TypeScript project with no existing AI/ML dependencies.

Detailed Findings #

Gemini 3 Pro (Text & Multimodal) #

What it is: Google's flagship reasoning model released November 2025, offering 1M token context window and advanced agentic capabilities.

Model ID: gemini-3-pro-preview

Why consider it:

How to implement:

 1import { GoogleGenAI } from "@google/genai";
 2
 3// API key from GEMINI_API_KEY env var or passed explicitly
 4const ai = new GoogleGenAI({});
 5
 6async function generateWithGemini3() {
 7  const response = await ai.models.generateContent({
 8    model: "gemini-3-pro-preview",
 9    contents: "Analyze this complex problem and provide a detailed solution",
10  });
11
12  console.log(response.text);
13}
14
15// With thinking level control
16async function generateWithThinking() {
17  const response = await ai.models.generateContent({
18    model: "gemini-3-pro-preview",
19    contents: "Solve this step by step: [complex math problem]",
20    config: {
21      thinkingLevel: "high", // "low" for faster, cheaper responses
22    },
23  });
24
25  console.log(response.text);
26}

Configuration Parameters:

Parameter Options Description
thinkingLevel low, high (default) Controls reasoning depth
mediaResolution low, medium, high Per-image token usage
temperature 0.0-2.0 (default: 1.0) Keep at 1.0 for best results

Trade-offs:

Nano Banana Pro (Image Generation) #

What it is: Google's advanced image generation model built on Gemini 3 Pro, offering studio-quality outputs with superior text rendering.

Model ID: gemini-3-pro-image-preview

Why consider it:

How to implement:

 1import { GoogleGenAI } from "@google/genai";
 2import * as fs from "node:fs";
 3
 4const ai = new GoogleGenAI({});
 5
 6// Basic text-to-image generation
 7async function generateImage() {
 8  const response = await ai.models.generateContent({
 9    model: "gemini-3-pro-image-preview",
10    contents: "A professional infographic showing TypeScript adoption trends",
11    config: {
12      responseModalities: ["TEXT", "IMAGE"],
13    },
14  });
15
16  for (const part of response.candidates[0].content.parts) {
17    if (part.text) {
18      console.log("Description:", part.text);
19    } else if (part.inlineData) {
20      const buffer = Buffer.from(part.inlineData.data, "base64");
21      fs.writeFileSync("output.png", buffer);
22      console.log("Image saved to output.png");
23    }
24  }
25}
26
27// Image editing with reference image
28async function editImage(imagePath: string, editPrompt: string) {
29  const imageData = fs.readFileSync(imagePath);
30  const base64Image = imageData.toString("base64");
31
32  const response = await ai.models.generateContent({
33    model: "gemini-3-pro-image-preview",
34    contents: [
35      { text: editPrompt },
36      {
37        inlineData: {
38          mimeType: "image/png",
39          data: base64Image,
40        },
41      },
42    ],
43    config: {
44      responseModalities: ["TEXT", "IMAGE"],
45    },
46  });
47
48  return response;
49}
50
51// Multi-turn image refinement
52async function iterativeImageGeneration() {
53  const chat = ai.chats.create({
54    model: "gemini-3-pro-image-preview",
55    config: {
56      responseModalities: ["TEXT", "IMAGE"],
57      tools: [{ googleSearch: {} }],
58    },
59  });
60
61  // First generation
62  let response = await chat.sendMessage({
63    message: "Create a logo for a TypeScript consulting company called 'TypeForge'",
64  });
65
66  // Refine in subsequent turns
67  response = await chat.sendMessage({
68    message: "Make the typography bolder and add a subtle anvil icon",
69    config: {
70      imageConfig: {
71        aspectRatio: "1:1",
72        imageSize: "2K",
73      },
74    },
75  });
76
77  return response;
78}
79
80// 4K high-resolution output
81async function generate4KImage() {
82  const response = await ai.models.generateContent({
83    model: "gemini-3-pro-image-preview",
84    contents: "A detailed architectural blueprint of a modern house",
85    config: {
86      responseModalities: ["IMAGE"],
87      imageConfig: {
88        imageSize: "4K",
89        aspectRatio: "16:9",
90      },
91    },
92  });
93
94  return response;
95}

Configuration Parameters:

Parameter Options Description
imageSize 1K, 2K, 4K Output resolution
aspectRatio 1:1, 16:9, 5:4, 9:16, 21:9 Output dimensions
responseModalities ["TEXT"], ["IMAGE"], ["TEXT", "IMAGE"] Output types

Trade-offs:

Nano Banana (Gemini 2.5 Flash Image) #

What it is: The faster, more cost-effective image generation option using Gemini 2.5 Flash.

Model ID: gemini-2.5-flash-image

Why consider it:

How to implement:

 1import { GoogleGenAI } from "@google/genai";
 2import * as fs from "node:fs";
 3
 4const ai = new GoogleGenAI({});
 5
 6async function quickImageGeneration() {
 7  const response = await ai.models.generateContent({
 8    model: "gemini-2.5-flash-image",
 9    contents: "A cute cartoon robot learning to code",
10    config: {
11      responseModalities: ["TEXT", "IMAGE"],
12    },
13  });
14
15  for (const part of response.candidates[0].content.parts) {
16    if (part.inlineData) {
17      const buffer = Buffer.from(part.inlineData.data, "base64");
18      fs.writeFileSync("quick-output.png", buffer);
19    }
20  }
21}

Trade-offs:

TypeScript SDK Setup #

Installation:

1npm install @google/genai

Environment Configuration:

1export GEMINI_API_KEY="your-api-key-here"

Full TypeScript Example:

  1// src/gemini-client.ts
  2import { GoogleGenAI } from "@google/genai";
  3import * as fs from "node:fs";
  4import * as path from "node:path";
  5
  6// Initialize client (reads GEMINI_API_KEY from environment)
  7const ai = new GoogleGenAI({});
  8
  9// Type definitions for better TypeScript support
 10interface GenerationConfig {
 11  model: string;
 12  contents: string | ContentPart[];
 13  config?: {
 14    responseModalities?: ("TEXT" | "IMAGE")[];
 15    thinkingLevel?: "low" | "high";
 16    imageConfig?: {
 17      imageSize?: "1K" | "2K" | "4K";
 18      aspectRatio?: "1:1" | "16:9" | "5:4" | "9:16" | "21:9";
 19    };
 20    tools?: Array<{ googleSearch: object }>;
 21  };
 22}
 23
 24interface ContentPart {
 25  text?: string;
 26  inlineData?: {
 27    mimeType: string;
 28    data: string;
 29  };
 30}
 31
 32// Text generation with Gemini 3
 33export async function generateText(prompt: string): Promise<string> {
 34  const response = await ai.models.generateContent({
 35    model: "gemini-3-pro-preview",
 36    contents: prompt,
 37  });
 38  return response.text;
 39}
 40
 41// Image generation with Nano Banana Pro
 42export async function generateImage(
 43  prompt: string,
 44  outputPath: string,
 45  options?: { size?: "1K" | "2K" | "4K"; aspectRatio?: string }
 46): Promise<void> {
 47  const response = await ai.models.generateContent({
 48    model: "gemini-3-pro-image-preview",
 49    contents: prompt,
 50    config: {
 51      responseModalities: ["TEXT", "IMAGE"],
 52      imageConfig: {
 53        imageSize: options?.size ?? "2K",
 54        aspectRatio: options?.aspectRatio ?? "1:1",
 55      },
 56    },
 57  });
 58
 59  for (const part of response.candidates[0].content.parts) {
 60    if (part.inlineData) {
 61      const buffer = Buffer.from(part.inlineData.data, "base64");
 62      fs.writeFileSync(outputPath, buffer);
 63      console.log(`Image saved to ${outputPath}`);
 64    }
 65  }
 66}
 67
 68// Image editing
 69export async function editImage(
 70  imagePath: string,
 71  editPrompt: string,
 72  outputPath: string
 73): Promise<void> {
 74  const imageData = fs.readFileSync(imagePath);
 75  const base64Image = imageData.toString("base64");
 76  const mimeType = imagePath.endsWith(".png") ? "image/png" : "image/jpeg";
 77
 78  const response = await ai.models.generateContent({
 79    model: "gemini-3-pro-image-preview",
 80    contents: [
 81      { text: editPrompt },
 82      { inlineData: { mimeType, data: base64Image } },
 83    ],
 84    config: {
 85      responseModalities: ["TEXT", "IMAGE"],
 86    },
 87  });
 88
 89  for (const part of response.candidates[0].content.parts) {
 90    if (part.inlineData) {
 91      const buffer = Buffer.from(part.inlineData.data, "base64");
 92      fs.writeFileSync(outputPath, buffer);
 93    }
 94  }
 95}
 96
 97// Chat session for multi-turn interactions
 98export async function createImageChat() {
 99  return ai.chats.create({
100    model: "gemini-3-pro-image-preview",
101    config: {
102      responseModalities: ["TEXT", "IMAGE"],
103    },
104  });
105}
106
107// Example usage
108async function main() {
109  // Generate text
110  const analysis = await generateText(
111    "Explain the benefits of TypeScript for large codebases"
112  );
113  console.log(analysis);
114
115  // Generate image
116  await generateImage(
117    "A minimalist logo for a TypeScript developer tools company",
118    "./output/logo.png",
119    { size: "2K", aspectRatio: "1:1" }
120  );
121
122  // Edit existing image
123  await editImage(
124    "./input/draft-logo.png",
125    "Make the colors more vibrant and add a subtle gradient",
126    "./output/final-logo.png"
127  );
128}
129
130main().catch(console.error);

Model Comparison Table #

Feature Gemini 3 Pro Nano Banana Pro Nano Banana (2.5 Flash)
Model ID gemini-3-pro-preview gemini-3-pro-image-preview gemini-2.5-flash-image
Primary Use Text/Reasoning Image Generation Image Generation
Context Window 1M tokens 65K tokens 1M tokens
Max Output 65K tokens 32K tokens 65K tokens
Max Resolution N/A 4K 2K
Reference Images N/A Up to 14 Up to 3
Text Rendering N/A Excellent Good
Free Tier Limited No Yes (limited)
Latency Medium Higher Lower
Best For Complex reasoning Professional images Quick prototypes

Recommendation #

For this TypeScript project, I recommend a tiered approach:

  1. Install the unified SDK: Use @google/genai v1.30.0+ exclusively. Do not use the deprecated @google/generative-ai package.

  2. Text/Reasoning Tasks: Start with gemini-2.5-flash for most tasks due to excellent cost-performance. Upgrade to gemini-3-pro-preview only for complex reasoning that requires the additional capability.

  3. Image Generation:

    • Use gemini-2.5-flash-image (Nano Banana) for prototyping and development
    • Use gemini-3-pro-image-preview (Nano Banana Pro) for production assets requiring text rendering or 4K output
  4. API Key Setup: Get your API key from Google AI Studio. For Nano Banana Pro, ensure billing is enabled.

This approach balances cost, performance, and capability while keeping the door open for the most advanced features when needed.

When NOT to Use This #

Sources #

last updated: