Convert any JSON value to compact, human-readable plain text. Designed to reduce LLM token costs while keeping data readable.
{ "name": "Delta", "email": "demo@example.com" }
↓
Name: Delta
Email: demo@example.com
~20–35% fewer tokens on typical API response payloads.
npm install humanize-jsonimport { humanizeJson } from "humanize-json";
const user = { name: "Delta", email: "demo@example.com", active: true };
humanizeJson(user);
// Name: Delta
// Email: demo@example.com
// Active: truehumanizeJson({
user: {
name: "Delta",
address: { city: "New York", zip: "10001" },
},
});
// User:
// Name: Delta
// Address:
// City: New York
// Zip: 10001// Bullet list (default)
humanizeJson({ tags: ["TypeScript", "LLM", "JSON"] });
// Tags:
// - TypeScript
// - LLM
// - JSON
// Numbered
humanizeJson({ steps: ["Install", "Configure", "Run"] }, { arrayMode: "numbered" });
// Steps:
// 1. Install
// 2. Configure
// 3. Run
// Inline
humanizeJson({ colors: ["red", "green", "blue"] }, { arrayMode: "inline" });
// Colors: [red, green, blue]
// Table (array of objects)
humanizeJson(
{ users: [{ name: "Alice", role: "Admin" }, { name: "Bob", role: "Editor" }] },
{ arrayMode: "table" }
);
// Users:
// Name Role
// ----- ------
// Alice Admin
// Bob EditorhumanizeJson({ user: { address: { city: "NYC" } } }, { mode: "flat" });
// user.address.city: NYChumanizeJson(
{ name: "Delta", password: "s3cr3t", apiKey: "xyz" },
{ exclude: ["password", "apiKey"] }
);
// Name: DeltahumanizeJson(
{ id: "usr_01", name: "Delta", email: "demo@example.com", createdAt: "2024-01-01" },
{ include: ["name", "email"] }
);
// Name: Delta
// Email: demo@example.comhumanizeJson(
{ active: true, price: 9.99, createdAt: "2024-01-15T00:00:00Z" },
{
formatters: {
active: (v) => (v ? "✓ Active" : "✗ Inactive"),
price: (v) => `$${Number(v).toFixed(2)}`,
createdAt: (v) => new Date(v as string).toLocaleDateString("en-US"),
},
}
);
// Active: ✓ Active
// Price: $9.99
// Created At: 1/15/2024humanizeJson(
{ userId: "123", ttl: 300 },
{ keyLabels: { userId: "User ID", ttl: "TTL (seconds)" } }
);
// User ID: 123
// TTL (seconds): 300humanizeJson(
{ name: "Delta", bio: null, note: "" },
{ skipEmpty: true }
);
// Name: Deltaimport { humanizeJson } from "humanize-json";
import type { ConversionResult } from "humanize-json";
const { text, stats } = humanizeJson(largePayload, { stats: true }) as ConversionResult;
console.log(text);
console.log(`Saved ~${stats.tokensSaved} tokens (${((1 - stats.compressionRatio) * 100).toFixed(1)}% reduction)`);import { parseAndConvert } from "humanize-json";
const text = parseAndConvert('{"name":"Delta","active":true}');
// Name: Delta
// Active: true| Signature | Returns |
|---|---|
humanizeJson(input, options?) |
string |
humanizeJson(input, { stats: true }) |
ConversionResult |
input — any JSON-serializable value: object, array, string, number, boolean, or null.
Parses a raw JSON string first, then converts. Throws on invalid JSON.
| Option | Type | Default | Description |
|---|---|---|---|
mode |
"indented" | "flat" |
"indented" |
Output structure. flat uses dot-notation keys (user.address.city: NYC). |
separator |
string |
": " |
String between key and value. |
arrayMode |
"bullet" | "numbered" | "inline" | "table" |
"bullet" |
How arrays are rendered. |
keyStyle |
"readable" | "original" | "uppercase" | "lowercase" |
"readable" |
Key name transformation. |
indent |
string |
" " |
Indentation string (any whitespace). |
maxDepth |
number |
Infinity |
Max nesting depth to expand. Deeper objects are JSON-stringified inline. |
include |
string[] |
— | Allowlist of key names to include. All others are excluded. |
exclude |
string[] |
— | Denylist of key names to exclude. |
skipEmpty |
boolean |
false |
Skip keys whose value is null, undefined, or "". |
maxValueLength |
number |
Infinity |
Truncate string values longer than this (appends …). |
formatters |
Record<string, (value, path) => string | undefined> |
— | Per-key value formatters. Return undefined to fall back to default. |
keyLabels |
Record<string, string> |
— | Override specific key labels. Takes precedence over keyStyle. |
stats |
boolean |
false |
Return a ConversionResult with token savings stats instead of a plain string. |
| Value | Example: firstName |
|---|---|
"readable" (default) |
First Name |
"original" |
firstName |
"uppercase" |
FIRSTNAME |
"lowercase" |
firstname |
"readable" converts camelCase, PascalCase, snake_case, and kebab-case to Title Case words.
| Value | Output |
|---|---|
"bullet" (default) |
- item per line |
"numbered" |
1. item per line |
"inline" |
[a, b, c] on one line |
"table" |
Aligned column table (for arrays of objects) |
Returned when stats: true is passed.
interface ConversionResult {
text: string;
stats: {
inputChars: number;
outputChars: number;
inputTokens: number; // estimated: ceil(chars / 4)
outputTokens: number;
compressionRatio: number; // outputChars / inputChars
tokensSaved: number; // inputTokens - outputTokens
};
}| Input | Output |
|---|---|
null |
"null" |
"" (empty string) |
"" |
42 |
"42" |
{} |
"" |
[] |
"[]" |
[1, 2, 3] |
"- 1\n- 2\n- 3" |
MIT