TanStack AI provides support for image generation through dedicated image adapters. This guide covers how to use the image generation functionality with OpenAI and Gemini providers.
Image generation is handled by image adapters that follow the same tree-shakeable architecture as other adapters in TanStack AI. The image adapters support:
import { generateImage } from '@tanstack/ai'
import { openaiImage } from '@tanstack/ai-openai'
// Create an image adapter (uses OPENAI_API_KEY from environment)
const adapter = openaiImage()
// Generate an image
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A beautiful sunset over mountains',
})
console.log(result.images[0].url) // URL to the generated image
import { generateImage } from '@tanstack/ai'
import { openaiImage } from '@tanstack/ai-openai'
// Create an image adapter (uses OPENAI_API_KEY from environment)
const adapter = openaiImage()
// Generate an image
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A beautiful sunset over mountains',
})
console.log(result.images[0].url) // URL to the generated image
import { generateImage } from '@tanstack/ai'
import { geminiImage } from '@tanstack/ai-gemini'
// Create an image adapter (uses GOOGLE_API_KEY from environment)
const adapter = geminiImage()
// Generate an image
const result = await generateImage({
adapter: geminiImage('imagen-3.0-generate-002'),
prompt: 'A futuristic cityscape at night',
})
console.log(result.images[0].b64Json) // Base64 encoded image
import { generateImage } from '@tanstack/ai'
import { geminiImage } from '@tanstack/ai-gemini'
// Create an image adapter (uses GOOGLE_API_KEY from environment)
const adapter = geminiImage()
// Generate an image
const result = await generateImage({
adapter: geminiImage('imagen-3.0-generate-002'),
prompt: 'A futuristic cityscape at night',
})
console.log(result.images[0].b64Json) // Base64 encoded image
All image adapters support these common options:
| Option | Type | Description |
|---|---|---|
| adapter | ImageAdapter | Image adapter instance with model (required) |
| prompt | string | Text description of the image to generate (required) |
| numberOfImages | number | Number of images to generate |
| size | string | Size of the generated image in WIDTHxHEIGHT format |
| modelOptions? | object | Model-specific options (renamed from providerOptions) |
| Model | Supported Sizes |
|---|---|
| gpt-image-1 | 1024x1024, 1536x1024, 1024x1536, auto |
| gpt-image-1-mini | 1024x1024, 1536x1024, 1024x1536, auto |
| dall-e-3 | 1024x1024, 1792x1024, 1024x1792 |
| dall-e-2 | 256x256, 512x512, 1024x1024 |
Gemini uses aspect ratios internally, but TanStack AI accepts WIDTHxHEIGHT format and converts them:
| Size | Aspect Ratio |
|---|---|
| 1024x1024 | 1:1 |
| 1920x1080 | 16:9 |
| 1080x1920 | 9:16 |
Alternatively, you can specify the aspect ratio directly in Model Options:
const result = await generateImage({
adapter: geminiImage('imagen-4.0-generate-001'),
prompt: 'A landscape photo',
modelOptions: {
aspectRatio: '16:9'
}
})
const result = await generateImage({
adapter: geminiImage('imagen-4.0-generate-001'),
prompt: 'A landscape photo',
modelOptions: {
aspectRatio: '16:9'
}
})
OpenAI models support model-specific Model Options:
const result = await generateImage({
adapter: openaiImage('gpt-image-1'),
prompt: 'A cat wearing a hat',
modelOptions: {
quality: 'high', // 'high' | 'medium' | 'low' | 'auto'
background: 'transparent', // 'transparent' | 'opaque' | 'auto'
outputFormat: 'png', // 'png' | 'jpeg' | 'webp'
moderation: 'low', // 'low' | 'auto'
}
})
const result = await generateImage({
adapter: openaiImage('gpt-image-1'),
prompt: 'A cat wearing a hat',
modelOptions: {
quality: 'high', // 'high' | 'medium' | 'low' | 'auto'
background: 'transparent', // 'transparent' | 'opaque' | 'auto'
outputFormat: 'png', // 'png' | 'jpeg' | 'webp'
moderation: 'low', // 'low' | 'auto'
}
})
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A futuristic car',
modelOptions: {
quality: 'hd', // 'hd' | 'standard'
style: 'vivid', // 'vivid' | 'natural'
}
})
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A futuristic car',
modelOptions: {
quality: 'hd', // 'hd' | 'standard'
style: 'vivid', // 'vivid' | 'natural'
}
})
const result = await generateImage({
adapter: geminiImage('imagen-4.0-generate-001'),
prompt: 'A beautiful garden',
modelOptions: {
aspectRatio: '16:9',
personGeneration: 'ALLOW_ADULT', // 'DONT_ALLOW' | 'ALLOW_ADULT' | 'ALLOW_ALL'
negativePrompt: 'blurry, low quality',
addWatermark: true,
outputMimeType: 'image/png', // 'image/png' | 'image/jpeg' | 'image/webp'
}
})
const result = await generateImage({
adapter: geminiImage('imagen-4.0-generate-001'),
prompt: 'A beautiful garden',
modelOptions: {
aspectRatio: '16:9',
personGeneration: 'ALLOW_ADULT', // 'DONT_ALLOW' | 'ALLOW_ADULT' | 'ALLOW_ALL'
negativePrompt: 'blurry, low quality',
addWatermark: true,
outputMimeType: 'image/png', // 'image/png' | 'image/jpeg' | 'image/webp'
}
})
The image generation result includes:
interface ImageGenerationResult {
id: string // Unique identifier for this generation
model: string // The model used
images: GeneratedImage[] // Array of generated images
usage?: {
inputTokens: number
outputTokens: number
totalTokens: number
}
}
interface GeneratedImage {
b64Json?: string // Base64 encoded image data
url?: string // URL to the image (OpenAI only)
revisedPrompt?: string // Revised prompt (OpenAI only)
}
interface ImageGenerationResult {
id: string // Unique identifier for this generation
model: string // The model used
images: GeneratedImage[] // Array of generated images
usage?: {
inputTokens: number
outputTokens: number
totalTokens: number
}
}
interface GeneratedImage {
b64Json?: string // Base64 encoded image data
url?: string // URL to the image (OpenAI only)
revisedPrompt?: string // Revised prompt (OpenAI only)
}
| Model | Images per Request |
|---|---|
| gpt-image-1 | 1-10 |
| gpt-image-1-mini | 1-10 |
| dall-e-3 | 1 |
| dall-e-2 | 1-10 |
| Model | Images per Request |
|---|---|
| imagen-3.0-generate-002 | 1-4 |
| imagen-4.0-generate-001 | 1-4 |
| imagen-4.0-fast-generate-001 | 1-4 |
| imagen-4.0-ultra-generate-001 | 1-4 |
Image generation can fail for various reasons. The adapters validate inputs before making API calls:
try {
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A cat',
size: '512x512', // Invalid size for DALL-E 3
})
} catch (error) {
console.error(error.message)
// "Size "512x512" is not supported by model "dall-e-3".
// Supported sizes: 1024x1024, 1792x1024, 1024x1792"
}
try {
const result = await generateImage({
adapter: openaiImage('dall-e-3'),
prompt: 'A cat',
size: '512x512', // Invalid size for DALL-E 3
})
} catch (error) {
console.error(error.message)
// "Size "512x512" is not supported by model "dall-e-3".
// Supported sizes: 1024x1024, 1792x1024, 1024x1792"
}
The image adapters use the same environment variables as the text adapters:
For production use or when you need explicit control:
import { createOpenaiImage } from '@tanstack/ai-openai'
import { createGeminiImage } from '@tanstack/ai-gemini'
// OpenAI
const openaiAdapter = createOpenaiImage('your-openai-api-key')
// Gemini
const geminiAdapter = createGeminiImage('your-google-api-key')
import { createOpenaiImage } from '@tanstack/ai-openai'
import { createGeminiImage } from '@tanstack/ai-gemini'
// OpenAI
const openaiAdapter = createOpenaiImage('your-openai-api-key')
// Gemini
const geminiAdapter = createGeminiImage('your-google-api-key')
