@rishabhbothra/imagery
v0.3.1
Published
Provider-agnostic TypeScript image generation library for OpenAI GPT Image and Google Gemini image models.
Maintainers
Readme
Imagery
Imagery is a provider-agnostic TypeScript library for image generation, image editing, and inpainting across OpenAI GPT Image and Google Gemini image models.
Current version: 0.3.1
The v1 API is intentionally small and explicit:
client.images.generate()for text-to-image generation.client.images.edit()for image-to-image editing with one or more reference images.client.images.inpaint()for pixel-mask inpainting where supported, or semantic inpainting where supported.
Provider differences are visible by design. OpenAI and Google do not expose the same capabilities, safety controls, cost units, or response metadata, and this library avoids hiding those differences behind a chat-style abstraction.
Install
pnpm add @rishabhbothra/imageryThe package is ESM-first and requires Node.js 20 or newer.
Documentation
The hosted documentation is published with GitHub Pages:
https://07rjain.github.io/imagery/
API reference:
https://07rjain.github.io/imagery/api/
Quickstart
import { ImageClient } from '@rishabhbothra/imagery';
const client = ImageClient.fromEnv({
defaultProvider: 'openai',
defaultModel: 'gpt-image-2',
});
const response = await client.images.generate({
prompt: 'A matte black water bottle on sandstone',
size: '1024x1024',
quality: 'low',
outputFormat: 'png',
});
const image = response.images[0];ImageClient.fromEnv() reads these environment variables:
OPENAI_API_KEY=
GEMINI_API_KEY=Do not expose provider API keys in browser code. Use this package from trusted server, worker, or edge environments.
Mock Provider
Use the built-in mock provider for tests and examples that should not call real APIs:
const client = ImageClient.fromEnv({
defaultProvider: 'mock',
defaultModel: 'mock-image',
});
const response = await client.images.generate({
prompt: 'A local deterministic test image',
});Editing With Multiple Images
Both provider adapters support reference-image edits where the selected model supports them:
const edited = await client.images.edit({
provider: 'google',
model: 'gemini-3.1-flash-image-preview',
prompt: 'Combine the product from the first image with the lighting from the second image.',
inputImages: [
{ data: firstImageBytes, mediaType: 'image/png' },
{ data: secondImageBytes, mediaType: 'image/jpeg' },
],
});Inpainting
OpenAI gpt-image-2 supports pixel-mask inpainting:
await client.images.inpaint({
provider: 'openai',
model: 'gpt-image-2',
prompt: 'Replace the sofa with a vintage leather chair.',
image: { data: roomBytes, mediaType: 'image/png' },
mask: { data: maskBytes, mediaType: 'image/png' },
});Google Gemini image models support semantic inpainting in v1:
await client.images.inpaint({
provider: 'google',
model: 'gemini-3.1-flash-image-preview',
prompt: 'Edit the supplied product photo.',
image: { data: productBytes, mediaType: 'image/jpeg' },
semanticMask: 'Change only the product color to navy blue.',
});Passing a pixel mask to a Google model throws an ImageCapabilityError.
Supported V1 Models
| Provider | Model | Notes |
| --- | --- | --- |
| OpenAI | gpt-image-2 | Generate, edit, pixel-mask inpaint, semantic inpaint |
| Google Gemini API | gemini-3-pro-image-preview | Generate, edit, semantic inpaint |
| Google Gemini API | gemini-3.1-flash-image-preview | Generate, edit, semantic inpaint |
Google support targets the Gemini API, not Google Cloud Vertex AI, Gemini Enterprise, or enterprise agent platform APIs.
Safety Controls
Safety relaxation is never automatic.
- OpenAI
moderation: 'low'must be set explicitly throughproviderOptions.openai. - Google
OFFandBLOCK_NONEsafety thresholds requireallowLessRestrictiveSafetySettings: true. - Safety and validation errors are not retried.
- Fallback from a safety-blocked provider is disabled unless
fallback.onSafetyErroris explicitly enabled.
Storage
The library does not write generated images to durable storage. Responses contain bytes and metadata:
const bytes = response.images[0]?.data;
const mediaType = response.images[0]?.mediaType;Applications own storage, CDN upload, retention, and access control.
Production Guides
- BYOK and multi-tenant clients
- Next.js long-running jobs
- Inpainting mask cookbook
- Usage metrics and billing
- Model capability discovery
- Errors and progress callbacks
Development
pnpm install
pnpm verifyUseful commands:
pnpm typecheck
pnpm test
pnpm test:consumer
pnpm docs:api
pnpm docs:buildLive tests are opt in and make real provider calls:
LIVE_IMAGE_TESTS=1 pnpm test:liveLive outputs are written to live-artifacts/, which is ignored by git.
Before Pushing
Run:
pnpm verifyCheck that local credentials and generated artifacts are not staged:
git status --shortThe following paths should stay local-only:
.env.env.*realtest/live-artifacts/node_modules/dist/
Design Principles
- Explicit image operations:
generate,edit, andinpaint. - Provider differences are preserved instead of hidden.
- Storage is app-owned; the library returns bytes and metadata.
- Safety relaxation is never automatic.
- Streaming is out of scope for v1.
- Core provider calls use
fetchand Web APIs for Node and edge-compatible runtimes.
