aminrafiei/laravel-toon

TOON (Token-Oriented Object Notation) format support for Laravel

Installs: 2

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/aminrafiei/laravel-toon

v1.0.0 2025-11-20 09:37 UTC

This package is not auto-updated.

Last update: 2025-12-12 20:24:59 UTC


README

A Laravel package that lets you return API responses in TOON format instead of JSON. If you're building APIs that talk to LLMs (like GPT or Claude), this can cut your token usage by 30-70%, which means real money saved on API costs.

What's TOON?

TOON (Token-Oriented Object Notation) is basically a more compact way to represent the same data you'd normally send as JSON. It uses indentation instead of braces, and for arrays of objects, it can use a table-like format that's way more efficient.

Here's the difference:

JSON (459 characters):

{
  "users": [
    {"id": 1, "name": "Alice", "email": "alice@example.com"},
    {"id": 2, "name": "Bob", "email": "bob@example.com"},
    {"id": 3, "name": "Charlie", "email": "charlie@example.com"}
  ]
}

TOON (146 characters):

users[3]{id,name,email}:
  1,Alice,alice@example.com
  2,Bob,bob@example.com
  3,Charlie,charlie@example.com

That's 68% smaller. For a million API calls, that's the difference between spending $500 and $160 on LLM costs.

Why Would I Use This?

Honestly, if you're just building a regular REST API for a web or mobile app, stick with JSON. Browsers and most HTTP clients expect JSON.

But if you're:

  • Sending data to GPT/Claude and paying per token
  • Building tools that integrate with LLMs
  • Processing large amounts of structured data through AI models
  • Trying to fit more context into LLM prompts

Then yeah, TOON can save you a bunch of money and let you send more data in less space.

Installation

composer require aminrafiei/laravel-toon

Usage

The nice thing is you barely have to change anything. Just extend ToonResource instead of JsonResource:

use Toon\ToonResource;

class UserResource extends ToonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

That's it. Your toArray() method stays exactly the same. All the Laravel Resource features you're used to (conditional attributes, relationships, etc.) still work.

In Your Controller

// Single resource
public function show(User $user)
{
    return new UserResource($user);
}

// Collection
public function index()
{
    return UserResource::collection(User::all());
}

The response comes out in TOON format with Content-Type: text/plain; charset=UTF-8.

Configuration

If you want to squeeze out even more efficiency, use tabs instead of commas:

class UserResource extends ToonResource
{
    protected string $delimiter = "\t";
}

You can also change indentation or enable key folding (which collapses single-key nested objects):

class UserResource extends ToonResource
{
    protected int $indentSize = 4;
    protected bool $keyFolding = true;
}

Or configure it per-request:

return (new UserResource($user))
    ->withDelimiter("\t")
    ->withKeyFolding(true);

How It Works

The encoder looks at your data and picks the most efficient format:

  • Simple values: name: John
  • Nested objects: Uses indentation
  • Arrays of primitives: tags[3]: admin,user,premium
  • Arrays of objects with same keys: Table format (super efficient)
  • Mixed arrays: List format with hyphens

It's all automatic. You don't have to think about it.

Real World Numbers

I tested this with actual API responses from a Laravel app:

  • Simple objects: ~30% smaller
  • Nested structures: ~27% smaller
  • Collections (the big win): ~68% smaller

That collection savings is where it really matters. If you're returning lists of users, products, whatever - that's where you see the biggest difference.

When NOT to Use This

Don't use TOON if:

  • You're building a public API (stick with JSON for compatibility)
  • Your clients are browsers or mobile apps
  • You're integrating with third-party services that expect JSON
  • You just don't want to deal with a non-standard format

TOON is specifically designed for AI/LLM use cases. For everything else, JSON is probably the better choice.

Requirements

  • PHP 8.1 or newer
  • Laravel 10 or 11

Testing

composer test

The Spec

This implements TOON Format Specification v1.5. The format is actually pretty well thought out - check out the spec if you're curious about the details.

Contributing

Found a bug? Have an idea? Open an issue or PR on GitHub. I'm pretty responsive.

License

MIT. Do whatever you want with it.

Links