helgesverre/toon
Token-Oriented Object Notation - A compact data format for reducing token consumption when sending structured data to LLMs
v3.2.1
263K downloads/mo
#2517 most downloaded on Packagist
HelgeSverre/toon-php
What this package is like to depend on
Last release 1 months ago
08 Jul 2026
Ships unpredictably
gaps range from 9 days to 7 months
Nearly every release is documented
notes for 10 of 10 stable releases
Nothing withdrawn
no release was ever pulled
10 months old
10 releases · first in 2025
10 releases in the last 12 months
see the full history below
Release timeline
10 releases · Oct 2025 to Jul 2026Releases
latest 10-
v3.2.108 Jul 2026Release notes
Open source →Changes in v3.2.1
Patch release fixing a decoder round-trip regression introduced in v3.2.0.
Fixed
- Decoder round-trip regression: quoted string values containing
[or{— for examplek: "a[3]b", or log lines carrying ANSI escape sequences such as"�[31m…"— were misread as array headers and raisedSyntaxException: Unterminated quoted stringon decode, so the encoder's own output could not be decoded back. Header detection now locates the:separator and the[/{markers outside quoted spans, so encoder output round-trips throughToon::decode()for every string value. The regression was introduced in v3.2.0; v3.1.0 was unaffected.
Internal
- Added comprehensive bidirectional round-trip test coverage (
tests/Spec/RoundTripSpecialStringsTest.php,tests/Spec/ComprehensiveRoundTripTest.php,tests/Spec/MalformedHeaderDecodeTest.php); line coverage raised from 90% to 96%. - Removed dead code (an orphaned validator cluster and unused
DelimiterParserhelpers) with no change to the public decode path.
Full Changelog: v3.2.0...v3.2.1
Release notes
Open source →Fixed
- Decoder round-trip regression (§6/§7.1): quoted string values containing
[or{— for examplek: "a[3]b", or log lines carrying ANSI escape sequences such as"[31m…"— were misread as array headers and raisedSyntaxException: Unterminated quoted stringon decode. Header detection now locates the:separator and the[/{markers outside quoted spans, so encoder output round-trips throughToon::decode()for every string value. Regression introduced in v3.2.0 (v3.1.0 was unaffected). Added comprehensive bidirectional round-trip test coverage (tests/Spec/RoundTripSpecialStringsTest.php,tests/Spec/ComprehensiveRoundTripTest.php).
- Decoder round-trip regression: quoted string values containing
-
v3.2.008 Jul 2026Release notes
Open source →Changes in v3.2.0
This release brings the library into conformance with TOON Specification v3.3 (upstream advanced v3.0 → v3.3) and adds a validation API.
Added
- TOON Specification v3.3 compliance. See
docs/SPEC.mdanddocs/CHANGELOG.md. - Unicode escapes (§7.1): the encoder emits C0 control characters (U+0000–U+001F except
\n,\r,\t) as\uXXXX; the decoder accepts\uXXXX(case-insensitive hex) and rejects lone surrogates and escapes with fewer than four hex digits. - Empty-array decoding (§9.1): the decoder now accepts the canonical
[]andkey: []forms in addition to the legacy[0]:/key[0]:forms. - Validation API:
Toon::validate(),toon_validate()andtoon_validate_lenient()for checking TOON syntax without decoding. - Spec conformance tests in
tests/Spec/Version31To33ComplianceTest.php.
Changed
- Number formatting (§2): finite numbers use canonical decimal only for
n = 0or1e-6 ≤ |n| < 1e21; values outside that range use exponent notation (lowercasee, explicit sign, e.g.1e+21,1e-7). Large in-domain floats are no longer quoted as strings, and very small numbers no longer underflow to0. - Control characters are no longer rejected on encode — they are escaped and preserved as data (§15).
- Strict decoding now rejects leading-zero / malformed bracket lengths such as
[03](§6, §14.2), header delimiter mismatches where the bracket delimiter differs from the field-list delimiter, e.g.rows[2|]{a,b}:(§6, §14.2), and duplicate sibling keys at the same depth (§8, §14.4). Non-strict mode treats malformed bracket tokens as literal keys and applies last-write-wins for duplicate keys.
Fixed
- Decoder: quoted object keys containing colons (e.g.
"App\Controller::method") now decode correctly (#4, #5). - Decoder:
key: []previously decoded tonulland a bare[]crashed with an uninitialized-offset warning; both now decode to an empty array. - Decoder — single-line list items (§9.2/§9.4/§10): a list item whose entire content is on the hyphen line now decodes by shape instead of as a plain string —
- [M]: …→ inner array,- key: …→ object, bare-→ empty object. This fixes round-trips for arrays of arrays and lists of single-field objects. - Decoder — empty document (§5): an empty or whitespace-only document decodes to an empty object in both modes, instead of throwing (strict) or returning
null(lenient). - Decoder — bare
key:(§8): decodes to an empty object, notnull. - Decoder — quoted header keys (§7.4): a quoted key prefix such as
"my-key"[3]:is unescaped. - Decoder — empty inline/tabular tokens (§9.1/§11.2): decode to the empty string instead of throwing (e.g.
[3]: a,,b→['a','','b']). - Decoder — backslash handling (§7.1/§11.2): an unquoted backslash is a literal character (escapes apply only inside quoted strings), and colon detection tracks quote state so a key ending in an escaped backslash (
"a\\": c) parses. - Options (§12):
EncodeOptions/DecodeOptionsrejectindent < 1;EncodeOptions::compact()now usesindent: 1so nested output round-trips. - Validation:
Toon::validate()now runs the full decoder internally and returnsfalseonly whendecode()throws, so validation and decoding can never disagree. The separate validator implementation was removed.
Full Changelog: v3.1.0...v3.2.0
Release notes
Open source →Added
- TOON Specification v3.3 compliance (upstream advanced v3.0 → v3.3). See
docs/SPEC.mdanddocs/CHANGELOG.md. - Unicode escapes (§7.1): encoder emits C0 control characters (U+0000–U+001F except
\n,\r,\t) as\uXXXX; decoder accepts\uXXXX(case-insensitive hex) and rejects lone surrogates and escapes with fewer than four hex digits. - Empty-array decoding (§9.1): decoder now accepts the canonical
[]andkey: []forms in addition to the legacy[0]:/key[0]:forms. - Validation API:
Toon::validate(),toon_validate()andtoon_validate_lenient()for checking TOON syntax without decoding. - Spec conformance tests in
tests/Spec/Version31To33ComplianceTest.php.
Changed
- Number formatting (§2): finite numbers use canonical decimal only for
n = 0or1e-6 ≤ |n| < 1e21; values outside that range use exponent notation (lowercasee, explicit sign, e.g.1e+21,1e-7). Large in-domain floats are no longer quoted as strings, and very small numbers no longer underflow to0. - Control characters: no longer rejected on encode — they are escaped and preserved as data (§15).
- Strict decoding: now rejects leading-zero / malformed bracket lengths such as
[03](§6, §14.2), header delimiter mismatches where the bracket delimiter differs from the field-list delimiter, e.g.rows[2|]{a,b}:(§6, §14.2), and duplicate sibling keys at the same depth (§8, §14.4). Non-strict mode treats malformed bracket tokens as literal keys and applies last-write-wins for duplicate keys.
Fixed
- Decoder: quoted object keys containing colons (e.g.
"App\\Controller::method") now decode correctly (#4, #5). - Decoder:
key: []previously decoded tonulland a bare[]crashed with an uninitialized-offset warning; both now decode to an empty array. - Decoder — single-line list items (§9.2/§9.4/§10): a list item whose entire content is on the hyphen line now decodes by shape instead of as a plain string —
- [M]: …→ inner array,- key: …→ object, bare-→ empty object. This fixes round-trips for arrays of arrays and lists of single-field objects. Nested arrays of objects/arrays as list items also round-trip now. - Decoder — empty document (§5): an empty or whitespace-only document decodes to an empty object (
[]) in both modes, instead of throwing (strict) or returningnull(lenient). - Decoder — bare
key:(§8): decodes to an empty object ([]), notnull. - Decoder — quoted header keys (§7.4): a quoted key prefix such as
"my-key"[3]:is unescaped. - Decoder — empty inline/tabular tokens (§9.1/§11.2): decode to the empty string instead of throwing (e.g.
[3]: a,,b→['a','','b']). - Decoder — backslash handling (§7.1/§11.2): an unquoted backslash is a literal character (escapes apply only inside quoted strings), and colon detection tracks quote state so a key ending in an escaped backslash (
"a\\": c) parses. - Options (§12):
EncodeOptions/DecodeOptionsrejectindent < 1(indent0cannot represent nesting);EncodeOptions::compact()now usesindent: 1so nested output round-trips. - Validation:
Toon::validate()now runs the full decoder internally and returnsfalseonly whendecode()throws, so validation and decoding can never disagree. The separate validator implementation (which had drifted from the decoder on duplicate keys, malformed brackets, and over-indented list fields) was removed.
- TOON Specification v3.3 compliance. See
-
v3.1.006 Dec 2025Release notes
Open source →Added
- toJSON() support: Objects with a
toJSON()method can now provide custom serialization, similar toJSON.stringifyin JavaScript
Fixed
- Decoder now treats negative leading zeros (
-05,-0001) as strings per spec §2.4
Changed
- TOON Specification v3.0 compliance for Section 10 (Objects as List Items)
Release notes
Open source →Added
- toJSON() support: Objects with a
toJSON()method can now provide custom serialization, similar toJSON.stringifyin JavaScript. The method takes priority overJsonSerializableinterface and includes recursion protection - v3.0 spec tests: Added
tests/Spec/Version3BreakingChangesTest.phpwith 6 tests verifying v3.0 compliance - Round-trip test: Added
test_tabular_first_field_in_list_item_round_tripto verify v3.0 format survives encode/decode cycles
Changed
- TOON Specification v3.0 compliance: Updated encoder to follow v3.0 breaking change in Section 10 (Objects as List Items)
- When a list-item object has a tabular array as its first field, tabular rows now appear at depth +2 (was depth +1)
- Sibling fields remain at depth +1 from the hyphen line
- Decoder: Already correctly handles both old and new indentation patterns (no changes required)
Fixed
- Decoder: Now correctly treats negative numbers with leading zeros (e.g.,
-05,-0001) as strings per TOON Specification §2.4
- toJSON() support: Objects with a
-
v3.0.026 Nov 2025Release notes
Open source →Breaking Changes
This major release aligns with TOON Specification v3.0, which standardizes the encoding for list-item objects whose first field is a tabular array.
Changed Behavior (Section 10 - Objects as List Items)
When a list-item object has a tabular array as its first field:
- Tabular rows: Now appear at depth +2 from the hyphen line (was depth +1)
- Sibling fields: Remain at depth +1 from the hyphen line
Output Format Change
Before (v2.x):
items[1]: - users[2]{id,name}: 1,Ada 2,Bob status: activeAfter (v3.0):
items[1]: - users[2]{id,name}: 1,Ada 2,Bob status: activeMigration Notes
- Encoder output changed: If you rely on exact output format matching, update your expectations
- Decoder backward compatible: The decoder handles both old and new indentation patterns
- Round-trip safe: encode → decode → encode produces consistent v3.0 format
Added
tests/Spec/Version3BreakingChangesTest.phpwith 6 tests verifying v3.0 compliance- Round-trip test for v3.0 tabular list-item format
Test Coverage
- Total: 551 tests, 1023 assertions (100% passing)
- PHPStan Level 9: 0 errors
- Full TOON Specification v3.0 conformance verified
-
v2.0.013 Nov 2025Release notes
Open source →Breaking Changes
This major release aligns with TOON Specification v2.0, which removes the optional
#length marker prefix from array headers.Removed Features
EncodeOptions::$lengthMarkerparameter removed from constructorEncodeOptions::withLengthMarkers()preset method removedEncodeOptions::withLengthMarker()fluent setter removed
Changed Behavior
- Encoder: Always emits
[N]format (e.g.,[3]: a,b,c) - Decoder: Rejects
[#N]format withSyntaxException
Migration Guide
Before (v1.x):
$options = EncodeOptions::withLengthMarkers(); $toon = Toon::encode($data, $options); // Output: [#3]: a,b,c
After (v2.0):
$options = EncodeOptions::default(); $toon = Toon::encode($data, $options); // Output: [3]: a,b,c
Fixed
Critical Fixes
- Locale-dependent float formatting: Fixed
sprintf()calls that caused decimal points to become commas in locales likeda_DK,de_DE. Now usesnumber_format()with explicit decimal separator for locale-independent formatting per TOON Spec §2.
Security
- Control character handling: Strings containing unsupported control characters (0x00-0x08, 0x0B, 0x0C, 0x0E-0x1F) are now rejected with
InvalidArgumentException. Only\n,\r, and\thave defined escape sequences per TOON Spec §7.1.
Bug Fixes
- Decoder error messages: Pattern
[N#]now produces correct v2.0 error message
Test Coverage
- Added 10 tests for v2.0 breaking change verification
- Added 5 tests for control character rejection
- Total: 544 tests, 997 assertions (100% passing)
- PHPStan Level 9: 0 errors
Documentation
- Updated
docs/SPEC-COMPLIANCE.mdwith control character policy and v2.0 compliance details - Full TOON Specification v2.0 conformance verified
Release notes
Open source →Breaking Changes
This major release aligns with TOON Specification v2.0, which removes the optional
#length marker prefix from array headers. The library version now matches the spec version for clarity.Removed Features
EncodeOptions::$lengthMarkerparameter - The optional length marker parameter has been removed from the constructorEncodeOptions::withLengthMarkers()preset - This preset method has been removedEncodeOptions::withLengthMarker()method - This fluent setter has been removed
Changed Behavior
- Encoder: Always emits
[N]format (e.g.,[3]: a,b,c). The deprecated[#N]format is no longer supported. - Decoder: Now rejects
[#N]format withSyntaxException. Previously accepted both[N]and[#N]formats.
Migration Guide
Before (v1.x):
use HelgeSverre\Toon\EncodeOptions; use HelgeSverre\Toon\Toon; // Using preset with length markers $options = EncodeOptions::withLengthMarkers(); $toon = Toon::encode($data, $options); // Output: [#3]: a,b,c // Using constructor $options = new EncodeOptions(lengthMarker: '#'); $toon = Toon::encode($data, $options);After (v2.0):
use HelgeSverre\Toon\EncodeOptions; use HelgeSverre\Toon\Toon; // Use default options (no length marker parameter) $options = EncodeOptions::default(); $toon = Toon::encode($data, $options); // Output: [3]: a,b,c // Constructor no longer accepts lengthMarker $options = new EncodeOptions(); $toon = Toon::encode($data, $options);Changed
- TOON Specification updated to v2.0 - Spec now explicitly prohibits
[#N]format - Encoder implementation - Removed all length marker logic, always emits
[N]format - Decoder implementation - Added strict validation to reject
[#N]format with clear error messages - EncodeOptions simplified - Removed
lengthMarkerparameter and related methods
Removed
EncodeOptions::$lengthMarkerpropertyEncodeOptions::withLengthMarkers()static methodEncodeOptions::withLengthMarker()instance method
Fixed
- Locale-dependent float formatting (Critical): Fixed
sprintf()calls that were locale-dependent, causing decimal points to become commas in locales likeda_DK,de_DE, etc. Now usesnumber_format()with explicit decimal point separator for guaranteed locale-independent formatting per TOON Spec §2. This ensures output is always valid regardless of system locale settings. - Control character handling (Security): Strings containing unsupported control characters (0x00-0x08, 0x0B, 0x0C, 0x0E-0x1F) are now rejected with
InvalidArgumentException. Per TOON Spec §7.1, only\n,\r, and\thave defined escape sequences. This prevents potential security issues from raw control characters in output. - Decoder error messages: Pattern
[N#](hash after digits) now produces the correct v2.0 error message instead of a generic error - Test coverage: Added 10 comprehensive tests for v2.0 breaking change verification (
tests/Spec/Version2BreakingChangesTest.php) - Test coverage: Added 5 tests for control character rejection
Documentation
- Updated
docs/SPEC-COMPLIANCE.mdwith control character policy and v2.0 verification details - Test count: 544 tests (up from 512 in v1.4.0), 997 assertions
-
v1.4.006 Nov 2025Release notes
Open source →Added
- Full TOON decoder implementation: Complete decoding functionality with strict mode support
- Parses all TOON formats: inline arrays, list arrays, tabular arrays, nested objects
- Strict mode validation (enabled by default) for spec compliance
- Configurable indentation and delimiter support
- Comprehensive error handling with specific exception types
- Round-trip encode/decode verified working perfectly
- Specification compliance documentation: Created comprehensive SPEC-COMPLIANCE.md
- Encoder conformance: 10/10 requirements verified
- Decoder conformance: 7/7 requirements verified
- Strict mode: 11/11 requirements verified
- Full TOON Specification v1.3 compliance verified
- Performance benchmarking: Comprehensive PHPBench suite for performance analysis
- EncodeBench: Measures encoding performance across data sizes (small, medium, large, xlarge) and format types (inline, tabular, list, nested)
- DecodeBench: Measures decoding/parsing performance with same variations
- ThroughputBench: Measures sustained operations per second for realistic workloads
- ScalabilityBench: Measures performance scaling from 10 to 100K items
- All benchmarks track execution time and memory usage
- GitHub Actions workflow: Automated performance benchmarking on every PR
- Runs benchmarks on PHP 8.1, 8.2, 8.3, 8.4
- Compares PR performance against main branch baseline
- Comments results directly on pull requests
- Detects performance regressions (>15% slower)
- Stores benchmark results as artifacts
- Justfile commands: New benchmark commands for local development
just benchmark-performance- Run PHPBench with default reportjust benchmark-perf-summary- Run with summary reportjust benchmark-all- Run both token efficiency and performance benchmarksjust benchmark-baseline- Store current performance as baselinejust benchmark-compare- Compare against stored baseline
- Documentation: Comprehensive README for performance benchmarks explaining metrics, usage, and interpretation
- Baseline benchmarks: Saved performance baselines before and after encoder refactoring for comparison
Changed
- Architecture refactoring: Converted Encoder from static methods to instance-based pattern
- Encoder now stores EncodeOptions and LineWriter as readonly properties
- Eliminated parameter threading through 9 methods (~30+ parameter passes)
- Matches Decoder's instance-based architecture for consistency
- Performance impact is negligible (< 3% worst case, often better)
- Decoder improvements: Completed Parser instance-based refactoring
- Fixed remaining DecodeOptions parameter bugs
- Parser now fully instance-based with stored configuration
- All 539 tests pass, PHPStan Level 9 clean
Release notes
Open source →Added
- Full TOON decoder implementation: Complete decoding functionality with strict mode support
- Parses all TOON formats: inline arrays, list arrays, tabular arrays, nested objects
- Strict mode validation (enabled by default) for spec compliance
- Configurable indentation and delimiter support
- Comprehensive error handling with specific exception types
- Round-trip encode/decode verified working perfectly
- Specification compliance documentation: Created comprehensive SPEC-COMPLIANCE.md
- Encoder conformance: 10/10 requirements verified
- Decoder conformance: 7/7 requirements verified
- Strict mode: 11/11 requirements verified
- Full TOON Specification v1.3 compliance verified
Changed
- Architecture refactoring: Converted Encoder from static methods to instance-based pattern
- Encoder now stores EncodeOptions and LineWriter as readonly properties
- Eliminated parameter threading through 9 methods (~30+ parameter passes)
- Matches Decoder's instance-based architecture for consistency
- Performance impact is negligible (< 3% worst case, often better)
- Decoder improvements: Completed Parser instance-based refactoring
- Fixed remaining DecodeOptions parameter bugs
- Parser now fully instance-based with stored configuration
- All 539 tests pass, PHPStan Level 9 clean
Added
- Specification compliance documentation: Created comprehensive SPEC-COMPLIANCE.md
- Encoder conformance: 10/10 requirements verified
- Decoder conformance: 7/7 requirements verified
- Strict mode: 11/11 requirements verified
- Full TOON Specification v1.3 compliance
- Performance benchmarking: Comprehensive PHPBench suite for performance analysis
- EncodeBench: Measures encoding performance across data sizes (small, medium, large, xlarge) and format types (inline, tabular, list, nested)
- DecodeBench: Measures decoding/parsing performance with same variations
- ThroughputBench: Measures sustained operations per second for realistic workloads
- ScalabilityBench: Measures performance scaling from 10 to 100K items
- All benchmarks track execution time and memory usage
- GitHub Actions workflow: Automated performance benchmarking on every PR
- Runs benchmarks on PHP 8.1, 8.2, 8.3, 8.4
- Compares PR performance against main branch baseline
- Comments results directly on pull requests
- Detects performance regressions (>15% slower)
- Stores benchmark results as artifacts
- Justfile commands: New benchmark commands for local development
just benchmark-performance- Run PHPBench with default reportjust benchmark-perf-summary- Run with summary reportjust benchmark-all- Run both token efficiency and performance benchmarksjust benchmark-baseline- Store current performance as baselinejust benchmark-compare- Compare against stored baseline
- Documentation: Comprehensive README for performance benchmarks explaining metrics, usage, and interpretation
- Baseline benchmarks: Saved performance baselines before and after encoder refactoring for comparison
- Full TOON decoder implementation: Complete decoding functionality with strict mode support
-
v1.3.003 Nov 2025Release notes
Open source →Changes in v1.3.0
Added
Native PHP enum support for both BackedEnum and UnitEnum types:
- BackedEnum values are extracted and normalized (e.g., Status::ACTIVE -> "active")
- UnitEnum names are extracted and normalized (e.g., Counting::TWO -> "TWO")
- Arrays of enum cases are properly encoded (e.g., HttpCode::cases() -> "[2]: 201,400")
Contributors
Thanks to @AmolKumarGupta for contributing this feature!
Release notes
Open source →Added
- Enum support: Native PHP enum normalization for both
BackedEnumandUnitEnumtypes- BackedEnum values are extracted and normalized (e.g.,
Status::ACTIVE→"active") - UnitEnum names are extracted and normalized (e.g.,
Counting::TWO→"TWO") - Arrays of enum cases are properly encoded (e.g.,
HttpCode::cases()→"[2]: 201,400") - Thanks to @AmolKumarGupta for the contribution!
- BackedEnum values are extracted and normalized (e.g.,
-
v1.2.028 Oct 2025Release notes
Open source →Changes in v1.2.0
Fixed
- Empty array encoding now correctly outputs
[0]length marker- Before:
items: - After:
items[0]:
- Before:
Changed
- README token savings table updated with benchmark data
- Documentation improvements
Full changelog: https://github.com/HelgeSverre/toon-php/blob/main/CHANGELOG.md#120---2025-10-28
Release notes
Open source →Fixed
- Empty array encoding: Empty arrays now correctly output with
[0]length marker (e.g.,items[0]:)
Changed
- README: Updated token savings table with benchmark data
- README: Removed outdated empty array limitations section
- Empty array encoding now correctly outputs
-
v1.1.028 Oct 2025Release notes
Open source →Changes in v1.1.0
Added
- Justfile for task automation with commands for setup, testing, analysis, formatting, benchmarks, quality checks, and CI workflows
- Token efficiency benchmark suite comparing TOON vs JSON vs XML across 4 datasets (GitHub repos, analytics data, e-commerce orders, employee records)
- Support for Anthropic API token counting or estimation fallback in benchmarks
- PHPDoc documentation for Toon::encode() method
- Extended test coverage with 3 new test files
Changed
- Benchmark output formatting simplified to use clean, minimal text instead of decorative boxes
- README enhanced with additional examples
Benchmark Results
Token savings compared to other formats:
- GitHub Repositories: 46.7% vs JSON, 61.4% vs XML
- Analytics Data: 68.0% vs JSON, 81.4% vs XML
- E-Commerce Orders: 29.6% vs JSON, 54.3% vs XML
- Employee Records: 56.7% vs JSON, 70.6% vs XML
Full changelog: https://github.com/HelgeSverre/toon-php/blob/main/CHANGELOG.md#110---2025-10-28
Release notes
Open source →Added
- Justfile: Added comprehensive task automation with
justcommands for:- Setup and installation
- Running tests (with coverage and watch mode)
- Static analysis with PHPStan
- Code formatting with Pint
- Benchmarks (new!)
- Quality checks and CI workflows
- Benchmarks: Complete token efficiency benchmark suite comparing TOON vs JSON vs XML
- Four realistic datasets: GitHub repos, analytics data, e-commerce orders, employee records
- Support for Anthropic API token counting or estimation fallback
- Clean, minimal output formatting
- Markdown report generation
- Documentation: Added comprehensive PHPDoc for
Toon::encode()method - Tests: Added 3 new test files with extended edge cases and normalization tests
Changed
- Benchmark output: Replaced decorative box characters with clean, minimal formatting
- README: Enhanced with more examples and usage instructions
-
v1.0.027 Oct 2025Release notes
Open source →Initial Stable Release
TOON (Token-Oriented Object Notation) is a compact data format for reducing token consumption when sending structured data to Large Language Models.
Installation
composer require helgesverre/toon
Example
use HelgeSverre\Toon\Toon; echo Toon::encode([ 'items' => [ ['sku' => 'A1', 'qty' => 2, 'price' => 9.99], ['sku' => 'B2', 'qty' => 1, 'price' => 14.5] ] ]);
Output:
items[2]{sku,qty,price}: A1,2,9.99 B2,1,14.5Features
- Support for primitive types (strings, numbers, booleans, null)
- Objects with key-value pairs
- Arrays in multiple formats (primitive, tabular, nested)
- DateTime objects in ISO 8601 format
- Intelligent string quoting
- Configurable indentation and delimiters
- 133 tests, 181 assertions
Documentation
Full changelog: https://github.com/HelgeSverre/toon-php/commits/v1.0.0
Release notes
Open source →Added
- Initial stable release of TOON PHP implementation
- Core encoding functionality via
Toon::encode()static method - Support for primitive types (strings, numbers, booleans, null)
- Support for objects (associative arrays) with key-value pairs
- Support for arrays with multiple format options:
- Primitive arrays: inline comma-separated format
- Tabular arrays: efficient tabular format for uniform objects
- List format: for non-uniform or nested structures
- Special handling for DateTime objects (ISO 8601 format)
- Intelligent string quoting (only when necessary)
- Nested data structure support with indentation-based nesting
- Configuration options via
EncodeOptions:- Custom indentation (default: 2 spaces)
- Custom delimiters (comma, tab, pipe)
- Length marker prefix option
- Comprehensive test suite with 133 tests covering:
- Primitive values
- Objects and nested objects
- Arrays (primitive, tabular, and nested)
- Edge cases and special values
- Custom delimiters and formatting options
- Format invariants
- Complete documentation with usage examples
- PSR-4 autoloading
- PHP 8.1+ support with strict types
Features
- Token Efficiency: Achieves 30-60% token reduction compared to JSON
- Human Readable: Clean, indentation-based format similar to YAML
- Smart Formatting: Automatically chooses optimal format for different data structures
- Type Preservation: Properly handles PHP types including DateTime objects
- Safe String Handling: Intelligent quoting for special characters and ambiguous values
- Flexible Configuration: Customizable indentation, delimiters, and length markers
- PHP-Specific Optimizations: Handles PHP array semantics and type system
Technical Details
- Pure PHP implementation with no external dependencies
- Immutable
EncodeOptionswith fluent API - Static final class to prevent instantiation and inheritance
- Full PHPStan static analysis compliance
- Comprehensive PHPUnit test coverage
- Follows PHP-FIG coding standards (via Laravel Pint)