DEV Community

Cover image for How to Generate Images Using LLM Gateway and the Vercel AI SDK
smakosh
smakosh

Posted on

How to Generate Images Using LLM Gateway and the Vercel AI SDK

Image generation has become a core feature of modern AI applications. But integrating with multiple image providers — each with different APIs, pricing, and capabilities — can be a pain.

LLM Gateway simplifies this by giving you a single, OpenAI-compatible API for image generation across providers like Google Gemini, Alibaba Qwen, ByteDance Seedream, and more. In this guide, we'll walk through generating images using both the OpenAI SDK and the Vercel AI SDK.

Prerequisites

  1. Sign up at llmgateway.io and create a project
  2. Copy your API key
  3. Export it in your environment:
export LLM_GATEWAY_API_KEY="llmgtwy_XXXXXXXXXXXXXXXX"
Enter fullscreen mode Exit fullscreen mode

Option 1: The Images API (/v1/images/generations)

This is the simplest approach — a drop-in replacement for OpenAI's image generation endpoint.

Using curl

curl -X POST "https://api.llmgateway.io/v1/images/generations" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image-preview",
    "prompt": "A cute cat wearing a tiny top hat",
    "n": 1,
    "size": "1024x1024"
  }'
Enter fullscreen mode Exit fullscreen mode

Using the OpenAI SDK (Node.js)

import OpenAI from "openai";
import { writeFileSync } from "fs";

const client = new OpenAI({
  baseURL: "https://api.llmgateway.io/v1",
  apiKey: process.env.LLM_GATEWAY_API_KEY,
});

const response = await client.images.generate({
  model: "gemini-3-pro-image-preview",
  prompt: "A futuristic city skyline at sunset with flying cars",
  n: 1,
  size: "1024x1024",
});

response.data.forEach((image, i) => {
  if (image.b64_json) {
    const buf = Buffer.from(image.b64_json, "base64");
    writeFileSync(`image-${i}.png`, buf);
  }
});
Enter fullscreen mode Exit fullscreen mode

That's it — point baseURL to LLM Gateway and use the standard OpenAI SDK. No new libraries needed.

Option 2: The Vercel AI SDK (generateImage)

If you're already using the Vercel AI SDK, LLM Gateway has a native provider package: @llmgateway/ai-sdk-provider.

npm install @llmgateway/ai-sdk-provider ai
Enter fullscreen mode Exit fullscreen mode

Simple Image Generation

import { createLLMGateway } from "@llmgateway/ai-sdk-provider";
import { generateImage } from "ai";
import { writeFileSync } from "fs";

const llmgateway = createLLMGateway({
  apiKey: process.env.LLM_GATEWAY_API_KEY,
});

const result = await generateImage({
  model: llmgateway.image("gemini-3-pro-image-preview"),
  prompt: "A cozy cabin in a snowy mountain landscape at night with aurora borealis",
  size: "1024x1024",
  n: 1,
});

result.images.forEach((image, i) => {
  const buf = Buffer.from(image.base64, "base64");
  writeFileSync(`image-${i}.png`, buf);
});
Enter fullscreen mode Exit fullscreen mode

Conversational Image Generation with streamText

The real power comes when you combine image generation with chat. Using the chat completions approach, you can build conversational image generation — ask the model to create an image, then refine it through follow-up messages.

Here's a Next.js API route:

import { streamText, type UIMessage, convertToModelMessages } from "ai";
import { createLLMGateway } from "@llmgateway/ai-sdk-provider";

interface ChatRequestBody {
  messages: UIMessage[];
}

export async function POST(req: Request) {
  const body = await req.json();
  const { messages }: ChatRequestBody = body;

  const llmgateway = createLLMGateway({
    apiKey: process.env.LLM_GATEWAY_API_KEY,
    baseUrl: "https://api.llmgateway.io/v1",
  });

  try {
    const result = streamText({
      model: llmgateway.chat("gemini-3-pro-image-preview"),
      messages: convertToModelMessages(messages),
    });

    return result.toUIMessageStreamResponse();
  } catch {
    return new Response(
      JSON.stringify({ error: "LLM Gateway Chat request failed" }),
      { status: 500 },
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

On the frontend, use the useChat hook from @ai-sdk/react and render images from the assistant's response parts:

import { useChat } from "@ai-sdk/react";

export const ImageChat = () => {
  const { messages, status, sendMessage } = useChat();

  return (
    <div>
      {messages.map((m) => {
        if (m.role === "assistant") {
          const textContent = m.parts
            .filter((p) => p.type === "text")
            .map((p) => p.text)
            .join("");

          const imageParts = m.parts.filter(
            (p) => p.type === "file" && p.mediaType?.startsWith("image/"),
          );

          return (
            <div key={m.id}>
              {textContent && <p>{textContent}</p>}
              {imageParts.map((part, idx) => (
                <img
                  key={idx}
                  src={`data:${part.mediaType};base64,${part.url}`}
                  alt="Generated image"
                />
              ))}
            </div>
          );
        }

        return (
          <div key={m.id}>
            {m.parts.map((p, i) =>
              p.type === "text" ? <p key={i}>{p.text}</p> : null
            )}
          </div>
        );
      })}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

You can also use the pre-built <Image /> component from ai-elements for a polished rendering experience.

Option 3: Image Editing

LLM Gateway also supports editing existing images via /v1/images/edits. Pass an image URL (HTTPS or base64 data URL) along with your edit prompt:

curl -X POST "https://api.llmgateway.io/v1/images/edits" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      {
        "image_url": "https://example.com/source-image.png"
      }
    ],
    "prompt": "Add a watercolor effect to this image",
    "model": "gemini-3-pro-image-preview",
    "quality": "high",
    "size": "1024x1024"
  }'
Enter fullscreen mode Exit fullscreen mode

Switching Providers

The best part: switching image providers is a one-line change. Just swap the model string:

// Google Gemini
model: "gemini-3-pro-image-preview"

// Alibaba Qwen (from $0.03/image)
model: "alibaba/qwen-image-plus"

// ByteDance Seedream (up to 4K output)
model: "bytedance/seedream-4-5"

// Z.AI CogView (great for text in images)
model: "zai/cogview-4"
Enter fullscreen mode Exit fullscreen mode

Each provider has different strengths:

Provider Model Price Best For
Google gemini-3-pro-image-preview Varies General purpose, high quality
Alibaba alibaba/qwen-image-max $0.075/image Highest quality
Alibaba alibaba/qwen-image-plus $0.03/image Best value
ByteDance bytedance/seedream-4-5 $0.045/image Up to 4K, multi-image fusion
Z.AI zai/cogview-4 $0.01/image Cheapest, bilingual text rendering

Customizing Output

Use the image_config parameter (chat completions) or standard size/quality params (images API) to control output:

# Google: aspect ratio + resolution
"image_config": {
  "aspect_ratio": "16:9",
  "image_size": "4K"
}

# Alibaba: pixel dimensions + seed for reproducibility
"image_config": {
  "image_size": "1024x1536",
  "seed": 42
}
Enter fullscreen mode Exit fullscreen mode

Wrapping Up

With LLM Gateway, image generation becomes provider-agnostic. Whether you're using the OpenAI SDK, Vercel AI SDK, or raw HTTP — you get one API, multiple providers, and the flexibility to switch models without changing your code.

Resources:

Get started →

Top comments (0)