Skip to content

ssafayet/humanize-json

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

humanize-json

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.


Installation

npm install humanize-json

Quick Start

import { humanizeJson } from "humanize-json";

const user = { name: "Delta", email: "demo@example.com", active: true };

humanizeJson(user);
// Name: Delta
// Email: demo@example.com
// Active: true

Examples

Nested objects

humanizeJson({
  user: {
    name: "Delta",
    address: { city: "New York", zip: "10001" },
  },
});
// User:
//   Name: Delta
//   Address:
//     City: New York
//     Zip: 10001

Arrays

// 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    Editor

Flat (dot-notation) mode

humanizeJson({ user: { address: { city: "NYC" } } }, { mode: "flat" });
// user.address.city: NYC

Exclude sensitive keys

humanizeJson(
  { name: "Delta", password: "s3cr3t", apiKey: "xyz" },
  { exclude: ["password", "apiKey"] }
);
// Name: Delta

Include only specific keys

humanizeJson(
  { id: "usr_01", name: "Delta", email: "demo@example.com", createdAt: "2024-01-01" },
  { include: ["name", "email"] }
);
// Name: Delta
// Email: demo@example.com

Custom value formatters

humanizeJson(
  { 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/2024

Custom key labels

humanizeJson(
  { userId: "123", ttl: 300 },
  { keyLabels: { userId: "User ID", ttl: "TTL (seconds)" } }
);
// User ID: 123
// TTL (seconds): 300

Skip empty values

humanizeJson(
  { name: "Delta", bio: null, note: "" },
  { skipEmpty: true }
);
// Name: Delta

Token savings stats

import { 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)`);

Parse from a JSON string

import { parseAndConvert } from "humanize-json";

const text = parseAndConvert('{"name":"Delta","active":true}');
// Name: Delta
// Active: true

API

humanizeJson(input, options?)

Signature Returns
humanizeJson(input, options?) string
humanizeJson(input, { stats: true }) ConversionResult

input — any JSON-serializable value: object, array, string, number, boolean, or null.

parseAndConvert(jsonString, options?)

Parses a raw JSON string first, then converts. Throws on invalid JSON.


Options

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.

keyStyle values

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.

arrayMode values

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)

ConversionResult

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
  };
}

Edge cases

Input Output
null "null"
"" (empty string) ""
42 "42"
{} ""
[] "[]"
[1, 2, 3] "- 1\n- 2\n- 3"

License

MIT

About

Convert any JSON to compact plain text — reduce LLM token costs and improve readability

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors