Getting reliable, structured data from AI models used to be a nightmare of prompt engineering and regex parsing. Now, with JSON mode, you can guarantee that ChatGPT, Claude, and Gemini return valid JSON every single time. This guide shows you exactly how to use it.
What is JSON Mode?
JSON mode is a feature that constrains an AI model to only output valid JSON. Without it, models can return markdown, explanatory text, or malformed JSON that breaks your parser.
Without JSON Mode:
Sure! Here's the data you requested:
```json
{
"name": "John",
"age": 30
}
```
Let me know if you need anything else! Includes markdown, explanatory text—JSON.parse() fails!
With JSON Mode:
{
"name": "John",
"age": 30
} Pure JSON—parses perfectly every time.
OpenAI JSON Mode (GPT-4, GPT-4o)
OpenAI offers two approaches: basic JSON mode and the newer Structured Outputs. Let's start with basic JSON mode.
Basic JSON Mode
import OpenAI from 'openai';
const openai = new OpenAI();
async function extractUserData(text) {
const response = await openai.chat.completions.create({
model: "gpt-4o",
response_format: { type: "json_object" }, // Enable JSON mode
messages: [
{
role: "system",
content: `You are a data extraction assistant.
Extract user information and return JSON with these fields:
- name (string)
- email (string or null)
- age (number or null)
- interests (array of strings)`
},
{ role: "user", content: text }
]
});
return JSON.parse(response.choices[0].message.content);
}
// Usage
const result = await extractUserData(
"Hi, I'm Sarah Chen, 28 years old. I love hiking and photography."
);
// { name: "Sarah Chen", email: null, age: 28, interests: ["hiking", "photography"] } OpenAI Structured Outputs (Advanced)
In August 2024, OpenAI introduced Structured Outputs—a more powerful feature that guarantees the output matches a specific JSON Schema. This is the gold standard for reliability.
import OpenAI from 'openai';
import { z } from 'zod';
import { zodResponseFormat } from 'openai/helpers/zod';
const openai = new OpenAI();
// Define schema with Zod
const ProductSchema = z.object({
name: z.string().describe("Product name"),
price: z.number().describe("Price in USD"),
category: z.enum(["electronics", "clothing", "home", "other"]),
features: z.array(z.string()).describe("Key product features"),
inStock: z.boolean()
});
async function extractProduct(description: string) {
const response = await openai.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "Extract product information." },
{ role: "user", content: description }
],
response_format: zodResponseFormat(ProductSchema, "product")
});
// TypeScript knows this is the correct type!
return response.choices[0].message.parsed;
} Claude JSON Output
Anthropic's Claude doesn't have an official "JSON mode" toggle, but it's extremely good at following instructions. For reliable JSON, use Claude's Tool Use feature.
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic();
const extractionTool = {
name: "extract_person",
description: "Extract person information from text",
input_schema: {
type: "object",
properties: {
name: { type: "string", description: "Person's full name" },
email: { type: "string", description: "Email address" },
company: { type: "string", description: "Company name" },
title: { type: "string", description: "Job title" }
},
required: ["name"]
}
};
async function extractPersonClaude(text) {
const response = await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
tools: [extractionTool],
tool_choice: { type: "tool", name: "extract_person" }, // Force this tool
messages: [{ role: "user", content: `Extract person info: ${text}` }]
});
const toolUse = response.content.find(block => block.type === 'tool_use');
return toolUse.input; // Already parsed JSON!
} Gemini JSON Mode
Google's Gemini has native JSON mode support through the responseMimeType setting.
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function extractWithGemini(text) {
const model = genAI.getGenerativeModel({
model: "gemini-1.5-pro",
generationConfig: {
responseMimeType: "application/json" // Enable JSON mode
}
});
const prompt = `Extract event details and return JSON with:
- eventName (string)
- date (YYYY-MM-DD format)
- location (string)
- attendees (array of strings)
Text: ${text}`;
const result = await model.generateContent(prompt);
return JSON.parse(result.response.text());
} Provider Comparison
| Feature | OpenAI | Claude | Gemini |
|---|---|---|---|
| Basic JSON Mode | ✅ response_format | ⚠️ Prompt-based | ✅ responseMimeType |
| Schema Enforcement | ✅ Structured Outputs | ✅ Tool Use | ✅ responseSchema |
| Zod Integration | ✅ Official helper | ❌ Manual | ❌ Manual |
| Reliability | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
Common Issues & Solutions
Issue: AI Returns Markdown Code Blocks
Use JSON mode (OpenAI/Gemini) or Tool Use (Claude). If stuck with prompt-only, strip markdown:
const cleanJson = response
.replace(/```json\n?/g, '')
.replace(/```\n?/g, '')
.trim(); Issue: Wrong Field Types
Use Structured Outputs (OpenAI) or validate with Zod and retry on failure.
Issue: Truncated JSON
- Increase
max_tokens - Simplify your schema (fewer fields)
- Request fewer items in arrays
Production Tips
- Log Raw Responses: Always log the raw AI response before parsing for debugging
- Implement Retries: Even with JSON mode, implement retry logic for transient failures
- Set Timeouts: AI calls can hang—always set reasonable timeouts
- Monitor Costs: JSON mode uses more tokens (schema description). Track usage.
Conclusion
JSON mode transforms AI from a "maybe it'll work" tool into a reliable data processing system:
- OpenAI users: Use Structured Outputs with Zod for best results
- Claude users: Use Tool Use with forced tool selection
- Gemini users: Use responseMimeType with responseSchema
- Everyone: Always validate with Zod, implement retries, log everything
Use our JSON tools with the TS/Zod tab to generate TypeScript interfaces and Zod schemas from sample JSON. Perfect for AI integrations!