Atomic Composable Schemas for GPT-Image2 Prompts: A Developer’s Guide
Atomic composable schemas split prompts into five reusable parts—subject, lighting, materials, layout, and visual details—so you can generate, validate, and combine GPT-Image2 prompts programmatically.
If you're building tools or agents around GPT-Image2, hand-crafting long prompt strings quickly becomes unmaintainable. The atomic composable schema solves this by treating every prompt as an assembly of discrete, interchangeable components. This architecture powers the entire generation pipeline in the freestylefly/awesome-gpt-image-2 repository, making prompts deterministic, testable, and automation-friendly.
What Are Atomic Composable Schemas?
An atomic composable schema decomposes an image prompt into five core primitives:
| Component | Purpose | Example Value |
|---|---|---|
| Subject | The primary visual focus | "a vintage film camera" |
| Lighting | Illumination quality and direction | "soft window light" |
| Materials | Surface texture and physical properties | "brushed aluminum body" |
| Layout | Spatial composition and aspect ratio | "centered, 1:1 square" |
| Visual Details | Color palette, style, and decorative modifiers | "sepia tones, shallow depth of field" |
Each primitive is atomic—indivisible and self-contained—and composable, meaning any combination of valid primitives produces a coherent prompt.
As defined in the project README: "Atomic schema: split subjects, lighting, materials, layout, and visual details into composable parts" ([README.md](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/README.md)).
Why This Architecture Matters
- Validation at the component level: Each primitive can be checked against a known vocabulary (stored in
data/style-library.json) before assembly - Reusability across contexts: The same "neon back-light" lighting atom works for portraits, products, or landscapes
- Programmatic manipulation: Agents can override single atoms (swap lighting, keep subject) without regex-parsing long strings
- Deterministic caching: Identical atom combinations yield identical prompts, enabling result deduplication
How the Schema Maps to Source Code
The atomic design flows through three key layers in the codebase:
1. Token Definitions in the Style Library
All valid atomic values live in data/style-library.json. This file organizes thousands of terms into categories like "UI", "Poster", "Lighting", and "Material" that map directly to schema components.
// From data/style-library.json — category structure
{
"categories": [
{
"name": "UI",
"description": "User interface and dashboard visuals",
"guidance": {
"subject": "clean interface components",
"lighting": "flat, even illumination",
"materials": "matte surfaces, subtle shadows"
}
}
]
}
Each category's "guidance" object mirrors the five atomic fields, providing default values that users can override ([data/style-library.json](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/data/style-library.json)).
2. Schema Assembly in the Client
The submitPersonalGeneration function in src/apimartClient.js consumes atomic parts and routes them through the API:
// From src/apimartClient.js
import { buildApimartGenerationPayload } from "../shared/apimart.js";
export async function submitPersonalGeneration(prompt, apiKey, language) {
// prompt here is the fully composed string from atomic parts
const payload = buildApimartGenerationPayload(prompt, apiKey, language);
// POST to APIMart generation endpoint...
}
The function delegates payload construction to buildApimartGenerationPayload in shared/apimart.js, which serializes the atomic schema into the JSON request body ([src/apimartClient.js](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js)).
3. Payload Builder Implementation
The shared helper translates atomic components into the exact format the APIMart API expects:
// shared/apimart.js — payload structure matches atomic schema fields
function buildApimartGenerationPayload(prompt, apiKey, language) {
return {
api_key: apiKey,
prompt: prompt, // assembled from atomic parts
language: language,
// additional metadata derived from layout/material atoms...
};
}
This separation of concerns—definition (style library), composition (your code), and transmission (client builders)—enables clean testing and extension.
Practical Code Examples
Building Prompts from Atomic Parts
// Define reusable atoms
const ATOMS = {
subject: "a hydroponic herb garden",
lighting: "full-spectrum LED glow",
materials: "transparent nutrient solution, matte white pods",
layout: "isometric view, 3:2 aspect",
details: "vivid greens, technical blueprint aesthetic"
};
// Composable assembly function
function composePrompt(atoms) {
return [atoms.subject, atoms.lighting, atoms.materials, atoms.layout, atoms.details]
.filter(Boolean)
.join(", ");
}
const finalPrompt = composePrompt(ATOMS);
// Result: "a hydroponic herb garden, full-spectrum LED glow, transparent nutrient solution, matte white pods, isometric view, 3:2 aspect, vivid greens, technical blueprint aesthetic"
Conditional Atom Swapping
function generateProductShot(productName, mood = "professional") {
const bases = {
subject: productName,
layout: "centered, 1:1 square, generous padding"
};
const moodAtoms = {
professional: {
lighting: "softbox diffusion, neutral fill",
materials: "brushed steel, micro-suede",
details: "cool grays, minimal shadows"
},
dramatic: {
lighting: "hard rim light, deep shadows",
materials: "polished chrome, patent leather",
details: "high contrast, cinematic color grade"
}
};
return composePrompt({ ...bases, ...moodAtoms[mood] });
}
// Two distinct outputs from the same base atoms
generateProductShot("wireless earbuds", "professional");
generateProductShot("wireless earbuds", "dramatic");
Full API Submission
import { submitPersonalGeneration } from "./src/apimartClient.js";
const apiKey = process.env.APIMART_KEY;
const promptSchema = {
subject: "retro arcade cabinet",
lighting: "scanline bloom, CRT phosphor glow",
materials: "yellowed plastic, convex glass",
layout: "three-quarter view, 4:3",
details: "1980s nostalgia, slight screen curvature"
};
const prompt = composePrompt(promptSchema);
const taskId = await submitPersonalGeneration(prompt, apiKey, "en");
console.log(`Generation queued: ${taskId}`);
Extending the Schema
The five-atom design intentionally leaves room for expansion. Common additions in forked implementations include:
- Camera — focal length, aperture, sensor size
- Environment — indoor/outdoor, weather, time of day
- Post-processing — grain, vignette, chromatic aberration
To add a new atom, update three locations:
- Validation layer: Extend
data/style-library.jsonwith a new category - Composition layer: Modify
composePrompt()to include the new field - API layer: Ensure
buildApimartGenerationPayloadhandles any metadata the new atom requires
Summary
- Atomic composable schemas decompose GPT-Image2 prompts into subject, lighting, materials, layout, and visual details
- This design enables validation, reuse, and programmatic manipulation of image prompts
- The
freestylefly/awesome-gpt-image-2repository implements this through:data/style-library.json— token definitionssrc/apimartClient.js— API client consumptionshared/apimart.js— payload serialization
Frequently Asked Questions
How do I validate that my atomic parts are compatible?
Cross-reference each atom against the data/style-library.json category definitions. The repository doesn't ship a runtime validator, but you can build one by loading the JSON and checking that lighting, material, and layout values exist in their respective category arrays.
Can I omit atomic fields if they're not relevant?
Yes. The composePrompt() helper filters falsy values with .filter(Boolean), so partial schemas work fine. Just be aware that omitting layout may produce unpredictable aspect ratios from the API.
What's the performance cost of assembling prompts this way?
Negligible. String concatenation of five atoms is micro-optimization territory compared to the network round-trip to APIMart. The schema's real performance benefit is caching: identical atom hashes generate identical prompts, letting you skip duplicate API calls.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →