Multi-Provider AI Image Generation with real-time prompt flow visualization and Backblaze B2 cloud storage.
A polished reference application demonstrating side-by-side comparison of OpenAI and Google Gemini image generation models, with transparent streamed prompt engineering workflow and production-ready storage architecture.
- Next.js 14+ - React framework with App Router and Server Actions
- TypeScript - Type-safe development with strict mode
- OpenAI gpt-image-1 - DALL-E 3 image generation API
- Google Gemini Imagen 3.0 - State-of-the-art text-to-image generation
- Backblaze B2 - S3-compatible cloud storage at $6/TB/month
- Drizzle ORM - Type-safe database queries with SQLite
- Server-Sent Events - Real-time streaming of generation pipeline
- Multi-Provider Image Generation: Compare OpenAI and Google Gemini outputs side-by-side
- Real-time Prompt Flow: Stream generation pipeline steps (planning β thinking β prompt construction β generation)
- Version History: Track multiple generation attempts per prompt with full lineage
- Cost-effective Storage: Store generated images in Backblaze B2 with presigned URLs
- Production Architecture: SQLite database with Drizzle ORM for tracking generations and assets
- Prompt Engineering Transparency: Show LLM reasoning and prompt optimization process
- Node.js 18+ - Download here
- Backblaze B2 Account (free tier available)
- Create a bucket
- Generate an Application Key with
readFiles,writeFilespermissions
- OpenAI API Key (for DALL-E 3 / gpt-image-1)
- Google AI API Key (for Gemini Imagen 3.0)
git clone https://github.com/backblaze-b2-samples/image-generation-prompt-flow.git
cd image-generation-prompt-flow
npm installcp .env.example .envEdit .env with your credentials:
# Database
DATABASE_URL=./data/sqlite.db
# Backblaze B2 (S3-compatible)
B2_S3_ENDPOINT=https://s3.us-west-004.backblazeb2.com
B2_S3_REGION=us-west-004
B2_S3_ACCESS_KEY_ID=your_key_id
B2_S3_SECRET_ACCESS_KEY=your_secret_key
B2_S3_BUCKET=your-bucket-name
B2_S3_PRESIGN_TTL_SECONDS=900
# OpenAI (DALL-E 3)
OPENAI_API_KEY=sk-...
# Google AI (Gemini Imagen 3.0)
GOOGLE_AI_API_KEY=...Get your B2 endpoint and region from your bucket details page
./scripts/init-db.shOr manually:
npm run db:pushnpm run devThat's it! Open http://localhost:3000 in your browser.
- Enter an image generation prompt (e.g., "A futuristic cityscape at sunset")
- Select providers (OpenAI, Gemini, or both)
- Click "Generate"
- Watch the real-time prompt flow in the middle panel
- Compare provider outputs side-by-side in the right panel
π For detailed setup instructions, see SETUP.md
User β Prompt Input β Next.js Server Action
β
Request Analysis (LLM)
β
Thinking Process (LLM)
β
Prompt Construction (LLM)
β
Parallel Generation: OpenAI + Gemini
β
Generated Images β B2 Storage
β
SQLite DB (Drizzle ORM)
β
Client UI (SSE Streaming)
- User enters generation prompt in web UI
- Server Action initiates generation pipeline with SSE streaming
- Action Plan Phase: LLM analyzes intent, subjects, style requirements
- Thinking Phase: LLM reasons through prompt optimization strategy
- Prompt Construction: LLM generates provider-optimized prompts
- Parallel Generation: Both OpenAI and Gemini APIs called simultaneously
- Generated images uploaded to B2 with presigned URLs
- Database stores generation metadata, run versions, and asset references
- Client displays side-by-side comparison with full prompt flow history
generations: User prompts and metadataruns: Provider-specific attempts with version trackingassets: Generated images with B2 storage keys and URLs
- Left Panel: Generation list with new prompt form
- Middle Panel: Real-time prompt flow visualization (SSE streaming)
- Right Panel: Side-by-side provider comparison view
Perfect for demonstrating transparent AI image generation workflows for:
- Prompt Engineering Research: Study how prompts are optimized for different models
- Model Comparison: Evaluate OpenAI vs Gemini output quality and style
- Multi-Provider Workflows: Build applications that hedge across providers
- Marketing Teams: Generate multiple creative variations from single brief
- Product Design: Compare AI-generated design concepts
- Educational Tools: Teach prompt engineering and AI image generation
- Version Control: Track generation history and iterate on prompts
OpenAI (gpt-image-1 / DALL-E 3)
- Resolution: 1024x1024, 1792x1024, 1024x1792
- Quality: Standard or HD
- Style: Natural or Vivid
- Pricing: ~$0.04-0.12 per image
Google Gemini (Imagen 3.0)
- Resolution: 1024x1024, 1536x1536, up to 2048x2048
- Quality: High-fidelity photorealism
- Aspect Ratios: Square, landscape, portrait
- Pricing: Varies by resolution
The application uses a multi-stage LLM pipeline to optimize prompts:
- Action Plan: Analyze user intent and extract key attributes
- Thinking: Reason through prompt optimization strategies
- Prompt Construction: Generate provider-specific optimized prompts
- Generation: Execute parallel API calls
All stages stream via Server-Sent Events for real-time visibility.
- Provider: Backblaze B2
- API: S3-compatible with presigned URLs
- Pricing: $6/TB/month storage, uploads FREE
- TTL: Configurable presigned URL expiration (default 900s)
- Documentation: B2 S3-Compatible API Docs
- Engine: SQLite with better-sqlite3
- ORM: Drizzle with type-safe queries
- Migrations: Schema managed via drizzle-kit
- Schema: Generations, runs, assets with relational queries
- Protocol: Server-Sent Events (SSE)
- Transport: Next.js Server Actions with streaming responses
- Events: Typed event system for each pipeline stage
- Client: EventSource API with automatic reconnection
# Install Vercel CLI
npm i -g vercel
# Deploy
vercelEnvironment Variables: Add all .env variables in Vercel project settings.
Database: Use Turso, PlanetScale, or mounted storage for SQLite persistence.
- Set environment variables from
.env - Set build command:
npm run build - Set start command:
npm start - Ensure persistent volume for SQLite database
Turso (Recommended for SQLite):
turso db create image-gen
turso db show image-gen
# Update DATABASE_URL in .envAlternative: PostgreSQL with Drizzle adapter
# Type checking
npm run tsc --noEmit
# Linting
npm run lint
# Database studio
npm run db:studio
# Database migrations
npm run db:generate
npm run db:push- API rate limits apply to OpenAI and Google AI
- Generated images expire after presigned URL TTL
- SQLite may need migration for production scale
- Streaming requires persistent connection (no serverless edge)
- Provider-specific resolution and aspect ratio constraints
- Add more providers (Midjourney, Stable Diffusion, Anthropic)
- Support image editing and variations (inpainting, outpainting)
- Add prompt templates and style presets
- Implement user authentication and project workspaces
- Export generations as PDF or presentation
- Add cost tracking and usage analytics
- Support batch generation workflows
- Implement prompt library with favorites
- Add image upscaling and enhancement
- OpenAI Image Generation Guide - DALL-E 3 API documentation
- Google Gemini Imagen Docs - Imagen 3.0 text-to-image guide
- Next.js Server Actions - Server-side mutations and streaming
- Backblaze B2 Documentation - Cloud storage API docs
- Drizzle ORM - Type-safe database toolkit
- Server-Sent Events - SSE streaming protocol
AI Image Generation, Multi-Provider Comparison, OpenAI DALL-E 3, Google Gemini Imagen, Prompt Engineering, Next.js, TypeScript, Server-Sent Events, Real-time Streaming, Backblaze B2, S3-Compatible Storage, Drizzle ORM, SQLite, Side-by-Side Comparison
Problem: "Invalid API key" or authentication errors.
Solution:
- Verify API keys in
.envare correct and active - Check OpenAI key has billing enabled
- Ensure Google AI API key has Imagen API enabled
- Restart dev server after changing
.env
Problem: Images fail to upload to B2.
Solution:
- Verify B2 credentials in
.env - Check bucket exists and region matches
- Ensure Application Key has
writeFilespermission - Check network connectivity to B2 endpoint
Problem: Database connection or migration errors.
Solution:
- Run
npm run db:pushto sync schema - Delete
./data/sqlite.dband reinitialize - Check
DATABASE_URLpath is correct - Ensure
./datadirectory exists
Problem: Prompt flow doesn't stream in UI.
Solution:
- Check browser console for EventSource errors
- Verify Server Actions are enabled in Next.js config
- Ensure connection is not going through serverless edge
- Test with Chrome/Firefox (best SSE support)
OpenAI:
- Check for content policy violations in prompt
- Verify resolution parameters are valid
- Ensure sufficient API credits
Google Gemini:
- Confirm Imagen 3.0 is available in your region
- Check prompt doesn't exceed token limits
- Verify safety settings allow content
MIT License - see LICENSE for details.
