ploon
v1.0.7
Published
Path-Level Object Oriented Notation - The Most Token-Efficient Format for Nested Hierarchical Data
Downloads
321
Maintainers
Readme
🚀 PLOON: Path-Level Object Oriented Notation
The Most Token-Efficient Format for Nested Hierarchical Data
PLOON achieves 49% token reduction vs JSON and 14% better than TOON through dual path notation (depth:index for arrays, depth for objects) and single schema declaration, optimized for deeply nested structures with full nested object support.
Credits
Inspired by TOON Format. PLOON offers an alternative approach using path-based hierarchy instead of indentation, achieving comparable token efficiency with different trade-offs.
📊 Why PLOON?
When sending data to LLMs, every token counts. PLOON optimizes hierarchical data by:
- Path-based hierarchy: Eliminates nesting overhead (no indentation!)
- Dual path notation: depth:index for arrays, depth for objects
- Single schema declaration: Zero key repetition
- Dual format strategy: Human-readable + machine-optimized
Key Findings
| Metric | vs JSON | vs XML | vs YAML | vs TOON | |--------|---------|--------|---------|---------| | File Size (Standard) | 66.2% ↓ | 62.4% ↓ | 48.5% ↓ | 36.0% ↓ | | File Size (Minified) | 66.5% ↓ | 62.8% ↓ | 49.0% ↓ | 36.5% ↓ | | Token Count (Standard) | 49.1% ↓ | 48.7% ↓ | 24.8% ↓ | 14.1% ↓ | | Token Count (Minified) | 49.1% ↓ | 48.7% ↓ | 24.8% ↓ | 14.1% ↓ | | Round-Trip Accuracy | - | - | - | 100% (5/5) |
PLOON beats TOON on BOTH metrics:
- 36.0% smaller file size (36.5% minified)
- 14.1% fewer tokens with depth:index format + nested object support
Cost Savings (GPT-5 @ $1.25/1M tokens)
- Average savings: $616.25 per 1M API calls vs JSON
ROI Example (10M API calls/month):
- With JSON: $18,707.48/month
- With PLOON: $12,544.98/month
- Monthly Savings: $6,162.50 (32.9% reduction)
🎯 Features
✅ Nested objects support: Arrays #() and Objects {} notation
✅ Multi-format input: JSON, XML, YAML → PLOON
✅ Dual output: Standard (readable) or Compact (efficient)
✅ Fully configurable: Custom delimiters, separators, markers
✅ Zero dependencies: Native JSON parsing
✅ TypeScript: Full type safety
✅ Tree-shakeable: Import only what you need
✅ CLI tool: Convert files from command line
📦 Installation
# Core library
npm install ploon
# or
pnpm add ploon
# or
yarn add ploon
# CLI tool (optional)
npm install -g ploon-cli🚀 Quick Start
import { stringify, minify, fromJSON } from 'ploon'
// Your data
const data = {
products: [
{ id: 1, name: 'Shirt', price: 29.99 },
{ id: 2, name: 'Pants', price: 49.99 }
]
}
// Convert to PLOON Standard (human-readable)
const ploon = stringify(data)
console.log(ploon)
// [products#2](id,name,price)
//
// 1:1|1|Shirt|29.99
// 1:2|2|Pants|49.99
// Minify for production (token-optimized)
const compact = minify(ploon)
console.log(compact)
// [products#2](id,name,price);;1:1|1|Shirt|29.99;1:2|2|Pants|49.99
// 62.7% smaller than JSON! 🎉📖 API Reference
Core Functions
stringify(data, options?)
Convert JavaScript object to PLOON string.
import { stringify } from 'ploon'
const ploon = stringify(data, {
format: 'standard', // or 'compact'
config: {
fieldDelimiter: '|',
pathSeparator: ':',
// ... other options
}
})parse(ploonString, options?)
Convert PLOON string to JavaScript object.
import { parse } from 'ploon'
const data = parse(ploonString, {
strict: true, // Validate schema
config: { /* custom config */ }
})minify(ploonString)
Convert Standard format → Compact format (newlines → semicolons).
import { minify } from 'ploon'
const compact = minify(standardPloon)
// Reduces tokens further!prettify(ploonString)
Convert Compact format → Standard format (semicolons → newlines).
import { prettify } from 'ploon'
const readable = prettify(compactPloon)
// Makes debugging easier!Input Parsers
fromJSON(jsonString)
Parse JSON string to object (uses native JSON.parse).
import { fromJSON, stringify } from 'ploon'
const obj = fromJSON('{"name": "John"}')
const ploon = stringify(obj)fromXML(xmlString)
Parse XML string to object (uses fast-xml-parser).
import { fromXML, stringify } from 'ploon'
const obj = fromXML('<root><name>John</name></root>')
const ploon = stringify(obj)fromYAML(yamlString)
Parse YAML string to object (uses yaml).
import { fromYAML, stringify } from 'ploon'
const obj = fromYAML('name: John\nage: 30')
const ploon = stringify(obj)Validation
isValid(ploonString)
Check if a string is valid PLOON format.
import { isValid } from 'ploon'
if (isValid(input)) {
console.log('Valid PLOON!')
}validate(ploonString)
Get detailed validation results.
import { validate } from 'ploon'
const result = validate(input)
// { valid: boolean, errors?: string[], warnings?: string[] }🎨 Examples
Simple Data
const data = {
users: [
{ id: 1, name: 'Alice', email: '[email protected]' },
{ id: 2, name: 'Bob', email: '[email protected]' }
]
}
const ploon = stringify(data)
// [users#2](email,id,name)
//
// 1:1|[email protected]|1|Alice
// 1:2|[email protected]|2|BobNested Data (3 Levels)
const data = {
products: [
{
id: 1,
name: 'T-Shirt',
colors: [
{
name: 'Red',
sizes: [
{ size: 'S', stock: 50 },
{ size: 'M', stock: 30 }
]
}
]
}
]
}
const ploon = stringify(data)
// [products#1](colors#(name,sizes#(size,stock)),id,name)
//
// 1:1|1|T-Shirt
// 2:1|Red
// 3:1|S|50
// 3:2|M|30Custom Configuration
// CSV-style (comma delimiter, custom path separator)
const csvStyle = stringify(data, {
config: {
fieldDelimiter: ',',
pathSeparator: ':' // Can still use : or customize
}
})
// [products#2](id,name,price)
//
// 1:1,1,Shirt,29.99
// 1:2,2,Pants,49.99💻 CLI Usage
# Convert JSON to PLOON
ploon data.json
# Convert to compact format
ploon data.json --minify
ploon data.json --minify -o output.ploon
# Explicit input format
ploon --from=xml data.xml
ploon --from=yaml data.yaml
# Convert PLOON to JSON
ploon --to=json data.ploon
# Convert PLOON to XML
ploon --to=xml data.ploon -o output.xml
# Format conversion
ploon data.ploon --minify # Standard → Compact
ploon data.ploon --prettify # Compact → Standard
# Validation
ploon data.ploon --validate
# Show statistics
ploon data.json --stats
# Custom delimiters
ploon data.json --field-delimiter="," --path-separator="/"
# Config file
ploon data.json --config=custom.jsonCLI Options
-o, --output <file> Output file (default: stdout)
--from <format> Input format: json|xml|yaml (default: auto)
--to <format> Output format: json|xml|yaml (from PLOON)
--minify Output compact format
--prettify Output standard format
--validate Validate PLOON format
--stats Show token comparison
-c, --config <file> Custom configuration file
--field-delimiter <char> Field delimiter (default: |)
--path-separator <char> Path separator (default: :)
--array-marker <char> Array size marker (default: #)⚙️ Configuration
Default Configuration
{
fieldDelimiter: '|', // Separates values
pathSeparator: ':', // Separates depth:index (e.g., 5:1)
arraySizeMarker: '#', // Array length marker
recordSeparator: '\n', // Newline (standard) or ';' (compact)
escapeChar: '\\', // Escape special characters
schemaOpen: '[', // Schema opening bracket
schemaClose: ']', // Schema closing bracket
fieldsOpen: '(', // Fields opening paren
fieldsClose: ')', // Fields closing paren
nestedSeparator: '|' // Nested schema separator
}Presets
import { PLOON_STANDARD, PLOON_COMPACT } from 'ploon'
// Standard: newline-separated (human-readable)
stringify(data, { config: PLOON_STANDARD })
// Compact: semicolon-separated (token-optimized)
stringify(data, { config: PLOON_COMPACT })📐 Format Specification
Standard Format
[root#count](field1,field2|nested#(subfield1,subfield2))
1:1|value1|value2
2:1|subvalue1|subvalue2Compact Format
[root#count](field1,field2|nested#(subfield1,subfield2));1:1|val1|val2;2:1|sub1|sub2Path Notation
PLOON uses dual path notation to distinguish arrays from objects:
Arrays use depth:index format:
1:1- First item at depth 12:1- First child (depth 2) of item 1:13:1- First grandchild (depth 3)5:4- Fourth item at depth 5
Objects use depth format (depth + space):
2- Object at depth 23- Nested object at depth 34- Deeply nested object at depth 4
Schema Notation:
- Arrays:
fieldName#(nestedFields)- e.g.,items#(id,name,price) - Objects:
fieldName{nestedFields}- e.g.,address{street,city,zip} - Both can nest infinitely:
customer{name,address{city,country{code,name}}}
Escaping
Special characters are escaped with backslash \:
\|- Literal pipe\;- Literal semicolon\:- Literal colon\\- Literal backslash
📊 Benchmarks
Verified Real-World Results
From our examples:
| Example | JSON | PLOON | Savings | |---------|------|-------|---------| | Simple (2 products) | 166 chars | 62 chars | 62.7% | | Nested (8 items, 3 levels) | 565 chars | 313 chars | 44.6% |
PLOON vs TOON
Both formats achieve similar token efficiency (40-50% vs JSON), with different strengths:
PLOON Advantages:
- ✅ Explicit path relationships (depth:index format)
- ✅ Better for deep nesting (constant token cost per path)
- ✅ Path-based queries (easier filtering)
- ✅ No indentation parsing needed
TOON Advantages:
- ✅ More human-readable (visual hierarchy)
- ✅ Simpler for shallow structures
- ✅ Established format with broader adoption
Choose PLOON when: You have deep nesting (3+ levels), need path-based queries, or want explicit relationships.
Choose TOON when: You prioritize human readability and have shallow structures.
🧪 Examples Directory
Check out /examples for more:
basic-usage.js- Simple conversionnested-data.js- Deep nesting (3+ levels)multi-format.js- JSON, XML, YAML inputcustom-config.js- Custom delimiters
Run them:
node examples/basic-usage.js
node examples/nested-data.js🛠️ Development
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Type check
pnpm typecheck📝 TypeScript Support
Full TypeScript support with exported types:
import type {
PloonConfig,
StringifyOptions,
ParseOptions,
ValidationResult,
JsonValue,
JsonObject,
JsonArray
} from 'ploon'🤝 Contributing
Contributions welcome! Please check our Contributing Guide.
📄 License
MIT © Ciprian Spiridon
🔗 Links
- Website
- Specification
- npm Package
- GitHub
- TOON Format (Inspiration)
🎉 Credits
Inspired by TOON Format. PLOON offers an alternative approach using path-based hierarchy instead of indentation, achieving comparable token efficiency with different trade-offs.
Made with ❤️ for LLM optimization
