{"id":47336806,"url":"https://github.com/HelgeSverre/toon-php","last_synced_at":"2026-04-01T02:00:34.202Z","repository":{"id":321286287,"uuid":"1084131870","full_name":"HelgeSverre/toon-php","owner":"HelgeSverre","description":"Token-Oriented Object Notation - A compact data format for reducing token consumption when sending structured data to LLMs (PHP implementation)","archived":false,"fork":false,"pushed_at":"2025-12-06T05:30:19.000Z","size":539,"stargazers_count":109,"open_issues_count":0,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T21:35:15.018Z","etag":null,"topics":["ai","data-format","llm","php","serialization","token-compression","toon"],"latest_commit_sha":null,"homepage":"https://github.com/HelgeSverre/toon-php","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HelgeSverre.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-27T09:11:18.000Z","updated_at":"2026-01-29T14:53:53.000Z","dependencies_parsed_at":"2025-10-28T21:35:50.571Z","dependency_job_id":null,"html_url":"https://github.com/HelgeSverre/toon-php","commit_stats":null,"previous_names":["helgesverre/toon-php"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/HelgeSverre/toon-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelgeSverre%2Ftoon-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelgeSverre%2Ftoon-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelgeSverre%2Ftoon-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelgeSverre%2Ftoon-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HelgeSverre","download_url":"https://codeload.github.com/HelgeSverre/toon-php/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelgeSverre%2Ftoon-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31262837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T01:56:54.585Z","status":"online","status_checked_at":"2026-04-01T02:00:07.777Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","data-format","llm","php","serialization","token-compression","toon"],"created_at":"2026-03-17T22:00:50.936Z","updated_at":"2026-04-01T02:00:34.193Z","avatar_url":"https://github.com/HelgeSverre.png","language":"PHP","readme":"# TOON (Token-Oriented Object Notation)\n\n[![Packagist Version](https://img.shields.io/packagist/v/helgesverre/toon)](https://packagist.org/packages/helgesverre/toon)\n![Total Downloads](https://img.shields.io/packagist/dt/helgesverre/toon)\n[![License](https://img.shields.io/packagist/l/helgesverre/toon)](https://suno.com/song/ecb121f2-9db7-4f6a-880e-77a2aee7253f)\n[![Try it](https://img.shields.io/badge/try_it-ArrayAlchemy-4E45E2)](https://arrayalchemy.com/?format=toon-php)\n\nA PHP port of [toon-format/toon](https://github.com/toon-format/toon) - a compact data format designed to reduce token\nconsumption when sending structured data to Large Language Models.\n\n## Contents\n\n- [Quick Start](#quick-start) · [Basic Usage](#basic-usage) · [Decoding](#decoding-toon) · [Configuration](#configuration-options)\n- [Tutorials](#tutorials) · [Version Compatibility](#version-compatibility) · [Development](#development)\n\n## What is TOON?\n\nTOON is a compact, human-readable format for structured data optimized for LLM contexts. For format details and efficiency analysis, see the [TOON Specification](https://github.com/toon-format/spec).\n\n## Installation\n\nInstall via Composer:\n\n```bash\ncomposer require helgesverre/toon\n```\n\n## Requirements\n\n- PHP 8.1 or higher\n\n## Quick Start\n\n```php\nuse HelgeSverre\\Toon\\Toon;\n\n// Encode data\necho Toon::encode(['user' =\u003e 'Alice', 'score' =\u003e 95]);\n// user: Alice\n// score: 95\n\n// Decode back to PHP\n$data = Toon::decode(\"user: Alice\\nscore: 95\");\n// ['user' =\u003e 'Alice', 'score' =\u003e 95]\n```\n\nTry it online at [ArrayAlchemy](https://arrayalchemy.com/?format=toon-php).\n\n## Basic Usage\n\n```php\nuse HelgeSverre\\Toon\\Toon;\n\n// Simple values\necho Toon::encode('hello');        // hello\necho Toon::encode(42);             // 42\necho Toon::encode(true);           // true\necho Toon::encode(null);           // null\n\n// Arrays\necho Toon::encode(['a', 'b', 'c']);\n// [3]: a,b,c\n\n// Objects\necho Toon::encode([\n    'id' =\u003e 123,\n    'name' =\u003e 'Ada',\n    'active' =\u003e true\n]);\n// id: 123\n// name: Ada\n// active: true\n```\n\n## Decoding TOON\n\nTOON supports bidirectional conversion - you can decode TOON strings back to PHP arrays:\n\n```php\nuse HelgeSverre\\Toon\\Toon;\n\n// Decode simple values\n$result = Toon::decode('42');           // 42\n$result = Toon::decode('hello');        // \"hello\"\n$result = Toon::decode('true');         // true\n\n// Decode arrays\n$result = Toon::decode('[3]: a,b,c');\n// ['a', 'b', 'c']\n\n// Decode objects (returned as associative arrays)\n$toon = \u003c\u003c\u003cTOON\nid: 123\nname: Ada\nactive: true\nTOON;\n\n$result = Toon::decode($toon);\n// ['id' =\u003e 123, 'name' =\u003e 'Ada', 'active' =\u003e true]\n\n// Decode nested structures\n$toon = \u003c\u003c\u003cTOON\nuser:\n  id: 123\n  email: ada@example.com\n  metadata:\n    active: true\n    score: 9.5\nTOON;\n\n$result = Toon::decode($toon);\n// ['user' =\u003e ['id' =\u003e 123, 'email' =\u003e 'ada@example.com', 'metadata' =\u003e ['active' =\u003e true, 'score' =\u003e 9.5]]]\n```\n\n**Note**: TOON objects are decoded as PHP associative arrays, not objects.\n\n## Tabular Format\n\nTOON's most efficient format is for uniform object arrays:\n\n```php\necho Toon::encode([\n    'users' =\u003e [\n        ['id' =\u003e 1, 'name' =\u003e 'Alice', 'role' =\u003e 'admin'],\n        ['id' =\u003e 2, 'name' =\u003e 'Bob', 'role' =\u003e 'user'],\n    ]\n]);\n```\n\nOutput:\n\n```\nusers[2]{id,name,role}:\n  1,Alice,admin\n  2,Bob,user\n```\n\nField names are declared once in the header, then each row contains only values. This is where TOON achieves the largest token savings compared to JSON.\n\nSee [docs/EXAMPLES.md](docs/EXAMPLES.md) for more encoding examples.\n\n## Configuration Options\n\nCustomize encoding behavior with `EncodeOptions`:\n\n```php\nuse HelgeSverre\\Toon\\EncodeOptions;\n\n// Custom indentation (default: 2)\n$options = new EncodeOptions(indent: 4);\necho Toon::encode(['a' =\u003e ['b' =\u003e 'c']], $options);\n// a:\n//     b: c\n\n// Tab delimiter instead of comma (default: ',')\n$options = new EncodeOptions(delimiter: \"\\t\");\necho Toon::encode(['tags' =\u003e ['a', 'b', 'c']], $options);\n// tags[3\\t]: a\tb\tc\n\n// Pipe delimiter\n$options = new EncodeOptions(delimiter: '|');\necho Toon::encode(['tags' =\u003e ['a', 'b', 'c']], $options);\n// tags[3|]: a|b|c\n```\n\n## Special Value Handling\n\n### String Quoting\n\nTOON only quotes strings when necessary:\n\n```php\necho Toon::encode('hello');           // hello (no quotes)\necho Toon::encode('true');            // \"true\" (quoted - looks like boolean)\necho Toon::encode('42');              // \"42\" (quoted - looks like number)\necho Toon::encode('a:b');             // \"a:b\" (quoted - contains colon)\necho Toon::encode('');                // \"\" (quoted - empty string)\necho Toon::encode(\"line1\\nline2\");    // \"line1\\nline2\" (quoted - control chars)\n```\n\n### DateTime Objects\n\nDateTime objects are automatically converted to ISO 8601 format:\n\n```php\n$date = new DateTime('2025-01-01T00:00:00+00:00');\necho Toon::encode($date);\n// \"2025-01-01T00:00:00+00:00\"\n```\n\n### PHP Enums\n\nPHP enums are automatically normalized - BackedEnum values are extracted, UnitEnum names are used:\n\n```php\nenum Status: string {\n    case ACTIVE = 'active';\n    case INACTIVE = 'inactive';\n}\n\nenum Priority: int {\n    case LOW = 1;\n    case HIGH = 10;\n}\n\nenum Color {\n    case RED;\n    case GREEN;\n    case BLUE;\n}\n\n// BackedEnum with string value\necho Toon::encode(Status::ACTIVE);\n// active\n\n// BackedEnum with int value\necho Toon::encode(Priority::HIGH);\n// 10\n\n// UnitEnum (no backing value)\necho Toon::encode(Color::BLUE);\n// BLUE\n\n// Array of enum cases\necho Toon::encode(Priority::cases());\n// [2]: 1,10\n```\n\n### Special Numeric Values\n\nNon-finite numbers are converted to null:\n\n```php\necho Toon::encode(INF);     // null\necho Toon::encode(-INF);    // null\necho Toon::encode(NAN);     // null\n```\n\n## Helper Functions\n\nTOON provides global helper functions for convenience:\n\n```php\n// Basic encoding\n$toon = toon($data);\n\n// Decoding\n$data = toon_decode($toonString);\n\n// Lenient decoding (forgiving parsing)\n$data = toon_decode_lenient($toonString);\n\n// Compact (minimal indentation)\n$compact = toon_compact($data);\n\n// Readable (generous indentation)\n$readable = toon_readable($data);\n\n// Tabular (tab-delimited)\n$tabular = toon_tabular($data);\n\n// Compare with JSON\n$stats = toon_compare($data);\n// Returns: ['toon' =\u003e 450, 'json' =\u003e 800, 'savings' =\u003e 350, 'savings_percent' =\u003e '43.8%']\n\n// Get size estimate\n$size = toon_size($data);\n\n// Estimate token count (4 chars/token heuristic)\n$tokens = toon_estimate_tokens($data);\n```\n\n## Tutorials\n\nStep-by-step guides for integrating TOON with LLM providers:\n\n### Getting Started\n\n- **[Getting Started with TOON](tutorials/01-getting-started.md)** (10-15 min)\n  Learn the basics: installation, encoding, configuration, and your first LLM integration.\n\n### Framework Integrations\n\n- **[OpenAI PHP Client Integration](tutorials/02-openai-integration.md)** (15-20 min)\n  Integrate TOON with OpenAI's official PHP client. Covers messages, function calling, and streaming.\n\n- **[Laravel + Prism AI Application](tutorials/03-laravel-prism-integration.md)** (20-30 min)\n  Build a complete Laravel AI chatbot using TOON and Prism for multi-provider support.\n\n- **[Anthropic/Claude Integration](tutorials/06-anthropic-integration.md)** (20-25 min)\n  Leverage Claude's 200K context window with TOON optimization. Process large datasets efficiently.\n\n### Advanced Topics\n\n- **[Token Optimization Strategies](tutorials/04-token-optimization-strategies.md)** (20-25 min)\n  Deep dive into token economics, RAG optimization, and cost reduction strategies.\n\n- **[Building a RAG System with TOON and Ollama](tutorials/05-rag-system-ollama.md)** (30-40 min)\n  Create a production-ready RAG pipeline with TOON, Ollama embeddings, and vector similarity search.\n\nSee the [`tutorials/`](tutorials) directory for all tutorials and learning paths.\n\n## Version Compatibility\n\nThis library tracks the [TOON Specification](https://github.com/toon-format/spec). Major versions align with spec versions.\n\n| Library | Spec | Key Changes |\n|---------|------|-------------|\n| v3.1.0 | v3.0 | toJSON() method support, negative leading zeros fix |\n| v3.0.0 | v3.0 | List-item objects with tabular first field use depth +2 for rows |\n| v2.0.0 | v2.0 | Removed `[#N]` length marker; decoder rejects legacy format |\n| v1.4.0 | v1.3 | Full decoder, strict mode |\n| v1.3.0 | v1.3 | PHP enum support |\n| v1.2.0 | v1.3 | Empty array fix |\n| v1.1.0 | v1.3 | Benchmarks, justfile |\n| v1.0.0 | v1.3 | Initial release |\n\nFor format details and token efficiency analysis, see the [TOON Specification](https://github.com/toon-format/spec).\n\n## Format Rules\n\n### Objects\n\n- Key-value pairs with colons\n- Indentation-based nesting (2 spaces by default)\n- Empty objects shown as `key:`\n\n### Arrays\n\n- **Primitives**: Inline format with length `tags[3]: a,b,c`\n- **Uniform objects**: Tabular format with headers `items[2]{sku,qty}: A1,2`\n- **Mixed/non-uniform**: List format with hyphens\n\n### Indentation\n\n- 2 spaces per level (configurable)\n- No trailing spaces\n- No final newline\n\n## PHP-Specific Limitations\n\n### Numeric Key Handling\n\nPHP automatically converts numeric string keys to integers in arrays:\n\n```php\n// PHP automatically converts numeric keys\n$data = ['123' =\u003e 'value'];  // Key becomes integer 123\necho Toon::encode($data);    // \"123\": value (quoted as string)\n```\n\nThe library handles this by quoting numeric keys when encoding.\n\n## Use Cases\n\nTOON is ideal for:\n\n- Sending structured data in LLM prompts\n- Reducing token costs in API calls to language models\n- Improving context window utilization\n- Making data more human-readable in AI conversations\n\n**Note**: TOON is optimized for LLM contexts and is not intended as a replacement for JSON in APIs or data storage.\n\n## Differences from JSON\n\nTOON is not a strict superset or subset of JSON. Key differences:\n\n- Bidirectional encoding and decoding (objects decode as associative arrays)\n- Optimized for readability and token efficiency in LLM contexts\n- Uses whitespace-significant formatting (indentation-based nesting)\n- Includes metadata like array lengths and field headers for better LLM comprehension\n\n## Credits\n\n- Original TypeScript implementation: [toon-format/toon](https://github.com/toon-format/toon)\n- Specification: [toon-format/spec](https://github.com/toon-format/spec)\n- PHP port: [HelgeSverre](https://github.com/HelgeSverre)\n\n## License\n\n[MIT License](LICENSE)\n\n## Development\n\n### Testing\n\n```bash\ncomposer test                # Run tests\ncomposer test:coverage       # Generate coverage report\ncomposer analyse             # Static analysis\n```\n\n### Specification Sync\n\nKeep the library aligned with upstream spec changes:\n\n```bash\njust sync-spec    # Download latest SPEC.md from upstream\njust diff-spec    # Show diff after download\njust autofix      # Sync spec and launch Claude Code for compliance review\n```\n\nThe `autofix` command downloads the latest specification, then launches Claude Code in plan mode with the `/spec-review` prompt to analyze changes and propose implementation updates.\n\n### Benchmarks\n\n```bash\ncd benchmarks \u0026\u0026 composer install \u0026\u0026 composer run benchmark\n```\n\nSee [benchmarks/README.md](benchmarks/README.md) for details.\n","funding_links":[],"categories":["Natural Language Processing"],"sub_categories":["Utilities \u0026 Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHelgeSverre%2Ftoon-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHelgeSverre%2Ftoon-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHelgeSverre%2Ftoon-php/lists"}