A lightweight Laravel package that converts standard JSON into TOON format - a human-readable, ultra-minimal, line-based data format.
🇹🇷 Türkçe Dokümantasyon için tıklayın
- ✅ Convert JSON to TOON format
- ✅ Ultra-minimal, human-readable output
- ✅ Preserves JSON key ordering
- ✅ Supports nested arrays and objects
- ✅ CLI command for file conversion
- ✅ Laravel Facade support
- ✅ Full test coverage
Install the package via Composer:
composer require digitalcorehub/laravel-toonThe package will automatically register its service provider and facade.
- PHP 8.3 or higher
- Laravel 10.x, 11.x, or 12.x
The package provides global helper functions for easy access:
// Encode to TOON
$toon = toon_encode(['id' => 1, 'name' => 'Test']);
// or
$toon = toon_encode('{"id": 1, "name": "Test"}');
// Decode from TOON
$array = toon_decode("id, name;\n1, Test");use DigitalCoreHub\Toon\Facades\Toon;
// Encode from array
$json = [
'id' => 1,
'name' => 'Test Product',
'price' => 99.99
];
$toon = Toon::encode($json);
// Output:
// id, name, price;
// 1, Test Product, 99.99The package supports a fluent builder-style API:
// From JSON string
$toon = Toon::fromJson('{"id": 1, "name": "Test"}')->encode();
// From array
$toon = Toon::fromArray(['id' => 1, 'name' => 'Test'])->encode();
// From TOON string
$array = Toon::fromToon("id, name;\n1, Test")->decode();The fluent interface is especially useful for method chaining and readability.
$jsonString = '{"id": 1, "name": "Test Product", "price": 99.99}';
$toon = Toon::encode($jsonString);$json = [
'reviews' => [
[
'id' => 1,
'customer' => 'John Doe',
'rating' => 5
],
[
'id' => 2,
'customer' => 'Jane Smith',
'rating' => 4
]
]
];
$toon = Toon::encode($json);
// Output:
// reviews[2]{
// id, customer, rating;
// 1, John Doe, 5
// 2, Jane Smith, 4
// }$json = [
'product' => 'Laptop',
'specs' => [
'cpu' => 'Intel i7',
'ram' => '16GB'
],
'reviews' => [
['id' => 1, 'rating' => 5],
['id' => 2, 'rating' => 4]
]
];
$toon = Toon::encode($json);Use the @toon() directive in your Blade templates to display TOON output:
@toon($data)The directive automatically:
- Encodes the data to TOON format
- Wraps it in a
<pre>tag - Escapes HTML for safe output
Example:
<!-- In your Blade template -->
<div class="toon-output">
@toon(['id' => 1, 'name' => 'Test Product', 'price' => 99.99])
</div>Output:
<div class="toon-output">
<pre>id, name, price;
1, Test Product, 99.99</pre>
</div>Log data in TOON format using the Log::toon() macro:
use Illuminate\Support\Facades\Log;
$data = ['id' => 1, 'name' => 'Test'];
Log::toon($data); // Logs at 'info' level
// Specify log level
Log::toon($data, 'debug');
// Specify channel
Log::toon($data, 'info', 'daily');The macro encodes your data to TOON format and logs it through Laravel's logging system.
Get colored TOON output for console/terminal:
use DigitalCoreHub\Toon\Facades\Toon;
$data = ['id' => 1, 'name' => 'Test', 'active' => true];
$colored = Toon::console($data, $output); // $output is optional OutputInterface
// In Artisan commands
$this->line(Toon::console($data, $this->output));Syntax Highlighting:
- Keys: Yellow
- Strings: Green
- Numbers: Blue
- Booleans: Magenta
- Brackets: Cyan
If you have Laravel Debugbar installed, the package automatically registers a TOON panel that shows:
- Recent encode/decode operations
- Performance timing (duration in milliseconds)
- Metadata (key count, row count, line count)
- Input/output preview
The integration is automatic - no configuration needed. If Debugbar is not installed, the package works normally without it.
Note: Debugbar integration is optional and does not affect package functionality if Debugbar is not installed.
For large JSON files, use the streaming encoder to avoid loading everything into memory:
use DigitalCoreHub\Toon\Facades\Toon;
// Encode large JSON file to TOON format
Toon::encodeStream('storage/large.json', 'storage/large.toon');
// Support for Laravel Storage disks
Toon::encodeStream('local:data.json', 'local:data.toon');The streaming encoder:
- Reads JSON file efficiently
- Writes TOON output progressively
- Reduces memory usage for large files
- Supports both local paths and Laravel Storage disks
Get TOON output line by line using a generator:
use DigitalCoreHub\Toon\Facades\Toon;
$data = ['id' => 1, 'name' => 'Test', 'items' => [1, 2, 3]];
// Generate lines one by one
foreach (Toon::lazy($data) as $line) {
echo $line . "\n";
}
// Or write directly to file
Toon::lazy($data)->toFile('output.toon');
// Or get as array
$lines = Toon::lazy($data)->toArray();Lazy encoder is perfect for:
- Large datasets
- Real-time output
- Memory-constrained environments
- Terminal/console output
Enable compact mode for smaller, faster output:
// In config/toon.php
'compact' => true,Compact mode:
- Removes extra whitespace
- Uses minimal separators (no spaces after commas)
- Produces smaller files
- Faster encoding/decoding
Example:
config(['toon.compact' => true]);
$data = ['id' => 1, 'name' => 'Test'];
$toon = Toon::encode($data);
// Output: id,name;1,Test (no spaces)Measure performance with the benchmark command:
php artisan toon:bench tests/bench/large.jsonThe benchmark shows:
- Encode speed (milliseconds)
- Decode speed (milliseconds)
- Memory usage (peak and used)
- Total rows processed
- Total keys processed
- File size comparison
Example Output:
ENCODE: 87.23 ms
DECODE: 114.56 ms
Memory Peak: 4.3 MB
Memory Used: 2.1 MB
Rows: 220
Keys: 14
TOON Size: 15,432 bytes
JSON Size: 18,765 bytes
-
Use streaming for large files:
Toon::encodeStream($input, $output); // Memory-efficient
-
Enable compact mode in production:
config(['toon.compact' => true]); // Smaller, faster
-
Use lazy encoder for real-time output:
foreach (Toon::lazy($data) as $line) { // Process line by line }
-
Monitor performance:
php artisan toon:bench your-file.json
use DigitalCoreHub\Toon\Facades\Toon;
// Decode from TOON string
$toon = "reviews[1]{
id, customer, rating, comment, verified;
101, Alex Rivera, 5, Excellent!, true
}";
$array = Toon::decode($toon);
// Returns:
// [
// [
// 'id' => 101,
// 'customer' => 'Alex Rivera',
// 'rating' => 5,
// 'comment' => 'Excellent!',
// 'verified' => true
// ]
// ]$toon = "reviews[2]{
id, customer, rating;
1, Alice, 5
2, Bob, 4
}";
$array = Toon::decode($toon);
// Returns array with 2 review items$toon = "product, reviews;
Laptop
reviews[2]{
id, customer, rating;
1, Alice, 5
2, Bob, 4
}";
$array = Toon::decode($toon);
// Returns:
// [
// 'product' => 'Laptop',
// 'reviews' => [
// ['id' => 1, 'customer' => 'Alice', 'rating' => 5],
// ['id' => 2, 'customer' => 'Bob', 'rating' => 4]
// ]
// ]The decode method throws InvalidToonFormatException for invalid TOON formats:
use DigitalCoreHub\Toon\Exceptions\InvalidToonFormatException;
use DigitalCoreHub\Toon\Facades\Toon;
try {
$array = Toon::decode($toon);
} catch (InvalidToonFormatException $e) {
// Handle invalid TOON format
echo "Error: " . $e->getMessage();
}Common errors include:
- Missing semicolons in keys line (with line numbers)
- Mismatched key/value counts (with line numbers)
- Unclosed brackets
{or}(with descriptive messages) - Invalid array block formats
Example Error Messages:
// Before: "Mismatched key/value count"
// After: "Key count (4) does not match value count (3) at line 5."
// Before: "Keys line must end with semicolon"
// After: "Missing semicolon in header block at line 2. Found: id, name, price"use DigitalCoreHub\Toon\Toon;
class ProductController extends Controller
{
public function __construct(
private Toon $toon
) {}
public function export()
{
$data = Product::all()->toArray();
return $this->toon->encode($data);
}
}Convert JSON files to TOON format using the Artisan command:
php artisan toon:encode input.json output.toonOptions:
--previewor-p: Show colored preview of the output
Example:
# Convert a JSON file
php artisan toon:encode storage/data.json storage/data.toon
# With colored preview
php artisan toon:encode storage/data.json storage/data.toon --preview
# The command will:
# - Read JSON from input.json
# - Convert to TOON format
# - Save to output.toon
# - Show colored preview if --preview flag is usedConvert TOON files to JSON format using the Artisan command:
php artisan toon:decode input.toon output.jsonOptions:
--previewor-p: Show colored preview of the input
Example:
# Convert a TOON file
php artisan toon:decode storage/data.toon storage/data.json
# The command will:
# - Read TOON from input.toon
# - Convert to JSON format (pretty printed)
# - Save to output.json
# - Display meaningful errors on invalid inputError Handling:
If the TOON file has invalid format, the command will display an error message:
$ php artisan toon:decode invalid.toon output.json
Invalid TOON format: Keys line must end with semicolonMeasure TOON encode/decode performance:
php artisan toon:bench [file]Options:
file: Optional path to JSON file. If not provided, uses first file fromtests/bench/directory.
Example:
# Benchmark a specific file
php artisan toon:bench storage/large.json
# Use default benchmark file
php artisan toon:benchThe benchmark command displays:
- Encode speed (milliseconds)
- Decode speed (milliseconds)
- Memory usage (peak and used)
- Total rows and keys processed
- File size comparison (TOON vs JSON)
Save TOON files using Laravel Storage:
php artisan toon:store input.json output.toon --disk=publicOptions:
--disk: The storage disk to use (default: from configtoon.storage.default_disk)
Example:
# Store to default disk (local)
php artisan toon:store storage/data.json users.toon
# Store to public disk
php artisan toon:store storage/data.json users.toon --disk=public
# The command will:
# - Read JSON from input.json
# - Convert to TOON format
# - Store via Laravel Storage
# - Print saved file pathSave TOON data to Laravel Storage:
use DigitalCoreHub\Toon\Facades\Toon;
$data = ['id' => 1, 'name' => 'Test'];
// Store to default disk (from config)
$path = Toon::store('my-file', $data);
// Returns: "toon/my-file.toon"
// Store to specific disk
$path = Toon::store('my-file', $data, 'public');
// Returns: "toon/my-file.toon"
// Store with nested path (directory created automatically)
$path = Toon::store('exports/users', $data, 'local');
// Returns: "toon/exports/users.toon"Features:
- Automatically adds
.toonextension if missing - Creates directories automatically
- Uses default directory from config (
toon.storage.default_directory) - Returns full saved file path
Configuration:
// config/toon.php
'storage' => [
'default_disk' => 'local',
'default_directory' => 'toon',
],Download TOON data as a file response:
use DigitalCoreHub\Toon\Facades\Toon;
// In a controller
Route::get('/export/users', function () {
$users = User::all()->toArray();
return Toon::download('users', $users);
});
// With custom filename
return Toon::download('export-2024-01-01', $data);Response Headers:
Content-Type: text/toonContent-Disposition: attachment; filename="users.toon"
The download method:
- Automatically adds
.toonextension if missing - Streams response efficiently
- Sets proper headers for file download
Return TOON format in API responses:
use Illuminate\Support\Facades\Response;
// In a controller
public function index()
{
$data = Product::all()->toArray();
return response()->toon($data);
}Response Headers:
Content-Type: text/toon
Example Route:
// routes/api.php
Route::get('/products', function () {
return response()->toon(Product::all()->toArray());
});The response()->toon() macro:
- Encodes data to TOON format
- Sets
Content-Type: text/toonheader - Returns standard Laravel response
File Structure: After storing files, they will be located at:
storage/app/toon/*.toon (default disk: local)
storage/app/public/toon/*.toon (disk: public)
The TOON format follows these rules:
-
Objects: Keys are listed on the first line, followed by values on the next line
id, name, price; 1, Product Name, 99.99 -
Arrays: Display with size indicator
arrayName[count]{...}reviews[2]{ id, customer, rating; 1, John, 5 2, Jane, 4 } -
Minimal Syntax: Removes unnecessary
{},[], commas, and quotes where possible -
Order Preservation: Maintains the original JSON key ordering
-
Nested Support: Fully supports nested arrays and objects
To customize the package settings, you need to publish the configuration file to your Laravel application:
php artisan vendor:publish --tag=toon-configThis command will create a config/toon.php file in your Laravel project's config directory.
After publishing, the configuration file will be located at:
config/toon.php
The published configuration file contains the following options:
return [
/*
|--------------------------------------------------------------------------
| Indentation
|--------------------------------------------------------------------------
|
| The number of spaces used for indentation in the TOON output.
|
*/
'indentation' => 4,
/*
|--------------------------------------------------------------------------
| Key Separator
|--------------------------------------------------------------------------
|
| The separator used between keys in the TOON format.
|
*/
'key_separator' => ', ',
/*
|--------------------------------------------------------------------------
| Line Break
|--------------------------------------------------------------------------
|
| The line break character used in the TOON output.
|
*/
'line_break' => PHP_EOL,
/*
|--------------------------------------------------------------------------
| Strict Mode
|--------------------------------------------------------------------------
|
| When enabled, decoding will throw exceptions for any formatting issues.
| When disabled, it will attempt to parse more leniently.
|
*/
'strict_mode' => false,
/*
|--------------------------------------------------------------------------
| Preserve Order
|--------------------------------------------------------------------------
|
| Whether to preserve the original JSON key ordering in the output.
|
*/
'preserve_order' => true,
/*
|--------------------------------------------------------------------------
| Storage Configuration
|--------------------------------------------------------------------------
|
| Configuration for storing TOON files using Laravel Storage.
|
*/
'storage' => [
'default_disk' => 'local',
'default_directory' => 'toon',
],
];You can access configuration values in your code:
use Illuminate\Support\Facades\Config;
$indentSize = config('toon.indentation');
$preserveOrder = config('toon.preserve_order');
$compact = config('toon.compact');Note: The configuration file is optional. If you don't publish it, the package will use default values.
Run the test suite:
composer test
# or
vendor/bin/phpunitInput (JSON):
{
"id": 1,
"name": "Laptop",
"price": 1299.99
}Output (TOON):
id, name, price;
1, Laptop, 1299.99
Input (JSON):
[
{
"id": 1,
"customer": "Alice",
"rating": 5
}
]Output (TOON):
array[1]{
id, customer, rating;
1, Alice, 5
}
Input (JSON):
{
"product": "Smartphone",
"reviews": [
{"id": 1, "customer": "Bob", "rating": 5},
{"id": 2, "customer": "Charlie", "rating": 4}
]
}Output (TOON):
product, reviews;
Smartphone
reviews[2]{
id, customer, rating;
1, Bob, 5
2, Charlie, 4
}
Current version: v0.6.0
This version includes:
- ✅ JSON → TOON encoding
- ✅ TOON → JSON decoding
- ✅ File Storage - Save TOON files using Laravel Storage (
store) - ✅ Download Support - Download TOON files as HTTP responses (
download) - ✅ API Response Macro -
response()->toon()for API endpoints - ✅ Store Command -
php artisan toon:storefor CLI file storage - ✅ Streaming encoder for large files (
encodeStream) - ✅ Lazy encoder for line-by-line output (
lazy) - ✅ Benchmark command (
php artisan toon:bench) - ✅ Compact mode for smaller, faster output
- ✅ Experimental streaming decode (
decodeStream) - ✅ CLI commands (encode, decode, store) with colored preview
- ✅ Global helper functions (
toon_encode,toon_decode) - ✅ Fluent interface (
fromJson,fromArray,fromToon) - ✅ Blade directive
@toon()for easy template integration - ✅ Laravel Debugbar integration (auto-detected)
- ✅ Log::toon() macro for logging support
- ✅ Console styling with syntax highlighting
- ✅ Configurable formatting (indentation, separators, line breaks)
- ✅ Improved exception messages with line numbers
- ✅ Facade and DI support
- ✅ Comprehensive test coverage
- ✅ Error handling with custom exceptions
Contributions are welcome! Please feel free to submit a Pull Request.
The MIT License (MIT). Please see License File for more information.
Developed by DigitalCoreHub
Made with ❤️ for the Laravel community