Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build full-stack web applications powered by Google Gemini's Nano Banana & Nano Banana Pro image generation APIs. Use when creating Next.js image generators, editors, galleries, or any web app that integrates gemini-2.5-flash-image or gemini-3-pro-image-preview models. Covers React components, server actions, API routes, storage, rate limiting, and production deployment patterns.
.claude/skills/aiskillstore-nano-banana-builder/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 60% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 105% | 0% |
Build production-ready web applications powered by Google's Nano Banana image generation APIs—creating everything from simple text-to-image generators to sophisticated iterative editors with multi-turn conversation.
Use ONLY these exact model strings. Do not invent, guess, or add date suffixes.
| Model String (use exactly) | Alias | Use Case | |---------------------------|-------|----------| | gemini-2.5-flash-image | Nano Banana | Fast iterations, drafts, high volume | | gemini-3-pro-image-preview | Nano Banana Pro | Quality output, text rendering, 2K |
Common mistakes to avoid:
gemini-2.5-flash-preview-05-20 — wrong, date suffixes are for text modelsgemini-2.5-pro-image — wrong, 2.5 Pro doesn't do image generationgemini-3-flash-image — wrong, doesn't existgemini-pro-vision — wrong, that's for image input, not generationThe only valid image generation models are gemini-2.5-flash-image and gemini-3-pro-image-preview.
Nano Banana isn't just another image API—it's conversational by design. The core insight is that image generation works best as a dialogue, not a one-shot prompt.
Think of it as working with an AI art director:
gemini-2.5-flash-image for speed/iterations, gemini-3-pro-image-preview for quality/complexityChoose based on use case:
| Use Case | Model | Why | |----------|-------|-----| | Rapid iterations, drafts | gemini-2.5-flash-image | Fast (2-5s), lower cost per image | | Final output, quality | gemini-3-pro-image-preview | Superior quality, thinking, text rendering | | Text-heavy images | gemini-3-pro-image-preview | Best typography, 2K resolution | | Multi-turn editing | Either | Both support conversational editing | | High volume | gemini-2.5-flash-image | Lower cost, faster throughput |
typescript// app/actions/generate.ts 'use server' import { google } from '@ai-sdk/google' import { generateText } from 'ai' export async function generateImage(prompt: string) { const result = await generateText({ model: google('gemini-2.5-flash-image'), prompt, providerOptions: { google: { responseModalities: ['IMAGE'], imageConfig: { aspectRatio: '16:9' } } } }) return result.files[0] // { base64, uint8Array, mediaType } }
typescript// app/components/ImageGenerator.tsx 'use client' import { useChat } from '@ai-sdk/react' export function ImageGenerator() { const { append, messages, isLoading } = useChat({ api: '/api/generate' }) return ( <div> {messages.map(m => ( <div key={m.id}> {m.parts?.map((part, i) => part.type === 'image' && ( <img key={i} src={part.url} alt="Generated" /> ) )} </div> ))} <button disabled={isLoading} onClick={() => append({ role: 'user', content: 'A futuristic cityscape at dusk' })} > Generate </button> </div> ) }
For complete implementations including:
See references/advanced-patterns.md
For detailed configuration and operational concerns:
See references/configuration.md
❌ Inventing model names or adding date suffixes: Why wrong: Image generation models have specific names; date suffixes like -preview-05-20 are for text models only Better: Use exactly gemini-2.5-flash-image or gemini-3-pro-image-preview — no variations
❌ Using Gemini 2.5 Pro for images: Why wrong: Gemini 2.5 Pro doesn't generate images directly Better: Use gemini-2.5-flash-image or gemini-3-pro-image-preview
❌ Storing only base64 in database: Why wrong: Blobs database, expensive storage, slow retrieval Better: Store in object storage (Vercel Blob/S3), save URL only
❌ No rate limit handling: Why wrong: Will hit 429 errors in production, poor UX Better: Implement rate limiting with user-friendly error messages
❌ Ignoring multi-turn context: Why wrong: Wastes Nano Banana's conversational editing strength Better: Track chat history for iterative refinement
❌ Hardcoding API keys client-side: Why wrong: Exposes credentials, security risk Better: Use server actions / API routes with environment variables
❌ Using wrong aspect ratio: Why wrong: 21:9 on 1:1 request wastes tokens, unexpected crop Better: Match aspect ratio to intended use case
❌ No loading states: Why wrong: Image generation takes 5-30s, users think it's broken Better: Show progress indicators and estimated wait time
❌ Generating on every keystroke: Why wrong: Wastes quota, slow response Better: Debounce prompts, require explicit action
IMPORTANT: Every app should feel uniquely designed for its specific purpose.
Vary across dimensions:
Avoid overused patterns:
Context should drive design:
bash# .env.local GEMINI_API_KEY=your_api_key_here # For Vercel Blob storage BLOB_READ_WRITE_TOKEN=your_vercel_token # For S3 (optional) S3_BUCKET=your-bucket S3_ENDPOINT=https://your-endpoint.r2.cloudflarestorage.com S3_ACCESS_KEY_ID=your_key S3_SECRET_ACCESS_KEY=your_secret # For Upstash rate limiting (optional) UPSTASH_REDIS_REST_URL=your_url UPSTASH_REDIS_REST_TOKEN=your_token
bash# Install dependencies npm install @ai-sdk/google ai @ai-sdk/react @vercel/blob # Or if using separate packages npm install google-genai
Nano Banana enables conversational image generation that feels like working with a creative partner, not a tool.
The best apps:
You're building more than an image generator—you're creating a creative experience. Design it thoughtfully.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 18,355 | 16,915 | -8% | 1 | 1 | 0% | 2,639 | 4,821 | +83% | 0 | 0 | — |
case-20 | pass→pass | 22,157 | 31,718 | +43% | 1 | 1 | 0% | 3,205 | 6,675 | +108% | 0 | 0 | — |
case-02 | fail→pass | 30,272 | 39,833 | +32% | 1 | 1 | 0% | 6,075 | 9,705 | +60% | 0 | 0 | — |
case-03 | fail→pass | 25,282 | 33,698 | +33% | 1 | 1 | 0% | 3,738 | 7,491 | +100% | 0 | 0 | — |
case-04 | pass→pass | 20,850 | 32,885 | +58% | 1 | 1 | 0% | 3,768 | 7,355 | +95% | 0 | 0 | — |
case-05 | fail→pass | 19,993 | 17,100 | -14% | 1 | 1 | 0% | 2,837 | 4,418 | +56% | 0 | 0 | — |
case-06 | fail→pass | 16,263 | 13,104 | -19% | 1 | 1 | 0% | 1,847 | 3,782 | +105% | 0 | 0 | — |
case-07 | fail→pass | 18,392 | 6,356 | -65% | 1 | 1 | 0% | 2,238 | 3,563 | +59% | 0 | 0 | — |
case-08 | fail→pass | 10,134 | 5,783 | -43% | 1 | 1 | 0% | 1,910 | 3,459 | +81% | 0 | 0 | — |
case-09 | fail→pass | 18,333 | 14,769 | -19% | 1 | 1 | 0% | 2,410 | 4,133 | +71% | 0 | 0 | — |
case-10 | fail→pass | 18,965 | 15,306 | -19% | 1 | 1 | 0% | 2,581 | 3,657 | +42% | 0 | 0 | — |
case-11 | fail→pass | 20,485 | 19,487 | -5% | 1 | 1 | 0% | 2,514 | 4,857 | +93% | 0 | 0 | — |
case-12 | fail→pass | 26,004 | 31,832 | +22% | 1 | 1 | 0% | 5,115 | 7,693 | +50% | 0 | 0 | — |
case-13 | pass→pass | 29,950 | 30,272 | +1% | 1 | 1 | 0% | 4,734 | 7,401 | +56% | 0 | 0 | — |
case-14 | fail→pass | 14,994 | 4,374 | -71% | 1 | 1 | 0% | 1,715 | 3,025 | +76% | 0 | 0 | — |
case-15 | fail→pass | 14,501 | 8,553 | -41% | 1 | 1 | 0% | 1,562 | 2,870 | +84% | 0 | 0 | — |
case-16 | pass→pass | 14,212 | 14,732 | +4% | 1 | 1 | 0% | 2,187 | 3,978 | +82% | 0 | 0 | — |
case-17 | pass→pass | 18,379 | 23,917 | +30% | 1 | 1 | 0% | 3,465 | 6,968 | +101% | 0 | 0 | — |
case-18 | pass→pass | 19,411 | 21,292 | +10% | 1 | 1 | 0% | 2,424 | 5,433 | +124% | 0 | 0 | — |
case-19 | fail→pass | 22,186 | 19,184 | -14% | 1 | 1 | 0% | 2,627 | 4,887 | +86% | 0 | 0 | — |
case-21 | fail→pass | 20,454 | 18,967 | -7% | 1 | 1 | 0% | 2,516 | 4,707 | +87% | 0 | 0 | — |
case-22 | pass→pass | 14,100 | 2,969 | -79% | 1 | 1 | 0% | 1,645 | 2,785 | +69% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +68 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.