A robust TypeScript/JavaScript library for parsing JSON from potentially malformed text. Perfect for handling LLM responses that may contain extra text, markdown formatting, or slightly invalid JSON syntax.
- 🤖 LLM-Friendly: Designed specifically for parsing AI/LLM responses
- 🛠️ Auto-Repair: Attempts to fix common JSON formatting issues
- 📝 Markdown Support: Handles JSON inside markdown code blocks
- 🔍 Multiple Extraction: Finds and parses multiple JSON objects in a single text
- 🎯 Flexible Options: Configurable parsing behavior
- 🌐 Universal: Works in Node.js, Bun, browsers, and other JS environments
- 💪 TypeScript: Full TypeScript support with comprehensive type definitions
# npm
npm install graceful-json
# yarn
yarn add graceful-json
# pnpm
pnpm add graceful-json
# bun
bun add graceful-json
import { parseAllJSON, parseJSON } from 'graceful-json';
// Parse LLM response with extra text
const llmResponse = `
Sure! Here's the data you requested:
{"name": "John", "age": 30, "city": "New York"}
Hope this helps!
`;
const results = parseAllJSON(llmResponse);
console.log(results[0].value); // { name: "John", age: 30, city: "New York" }
// Extract just the values
const values = parseJSON(llmResponse);
console.log(values); // [{ name: "John", age: 30, city: "New York" }]
import { GracefulJSON, parseAllJSON, parseJSON } from 'graceful-json';
// Class based
const parser = new GracefulJSON({
includeArrays: true,
includePrimitives: false,
attemptRepair: true
});
const results = parser.parseAll(text);
// Function based
const allResults = parseAllJSON(text, { ... });
const onlyValues = parseJSON(text, { ... });
interface ParseOptions {
/** Whether to include arrays as valid JSON objects (default: true) */
includeArrays?: boolean;
/** Whether to include primitive values like strings, numbers (default: false) */
includePrimitives?: boolean;
/** Maximum depth to search for nested JSON (default: 10) */
maxDepth?: number;
/** Whether to attempt to fix common JSON formatting issues (default: true) */
attemptRepair?: boolean;
}
interface ParseResult {
/** The parsed JSON value */
value: any;
/** The original text that was parsed */
originalText: string;
/** Start position in the original input */
startIndex: number;
/** End position in the original input */
endIndex: number;
/** Whether the JSON was repaired during parsing */
wasRepaired: boolean;
}
const llmResponse = `
Here's your JSON data:
\`\`\`json
{
"users": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
}
\`\`\`
The data includes 2 users.
`;
const data = parseJSON(llmResponse);
console.log(data.users); // [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
const text = `
First: {"type": "user", "name": "Alice"}
Second: {"type": "admin", "name": "Bob"}
Array: [1, 2, 3]
`;
const values = parseJSON(text);
// Returns: [{"type": "user", "name": "Alice"}, {"type": "admin", "name": "Bob"}, [1, 2, 3]]
The library automatically attempts to fix:
- Single quotes → Double quotes
- Unquoted object keys
- Trailing commas
- Missing commas between elements
- JavaScript-style comments
- Common formatting issues
- ✅ Node.js (16+)
- ✅ Bun
- ✅ Modern browsers
- ✅ TypeScript
- ✅ ESM and CommonJS
MIT License
Pull requests and stars are always welcome. For more information, check out the GitHub repository.