laravel-superjson maintained by sulimanbenhalim
Description
SuperJSON format for Laravel - preserve JavaScript types in JSON (Beta: CSRF limitations)
Author
Last update
2025/12/06 02:18
(dev-main)
License
Downloads
1
Tags
Laravel SuperJSON
Type-preserving JSON serialization for Laravel APIs and JavaScript
⚠️ BETA VERSION: This package has known limitations with CSRF-protected POST requests. See CSRF_LIMITATION.md for details. Use API routes for POST requests.
Install
composer require sulimanbenhalim/laravel-superjson
Usage
Response Macros
// Type-preserving API responses
return response()->superjson([
'user' => $user,
'created_at' => now(),
'big_id' => new BigInt('12345678901234567890'),
'tags' => new SuperSet(['php', 'laravel']),
]);
// Short alias
return response()->sjson($data);
Request Helpers
// Parse SuperJSON from incoming requests
$data = request()->superjson();
$user = request()->superjson('user.name');
// Short alias
$data = request()->sjson();
Blade Directives
<script>
const data = @superjson($serverData);
// JavaScript types preserved: Date, BigInt, Set, Map, etc.
</script>
Middleware
// routes/api.php
Route::middleware(['superjson'])->group(function () {
Route::get('/users', UserController::class);
Route::post('/users', UserController::class);
});
Type Support
| PHP Type | JavaScript Type | Implementation |
|---|---|---|
| DateTime, Carbon | Date | Built-in |
| BigInt class | BigInt | Built-in |
| SuperSet class | Set | Built-in |
| SuperMap class | Map | Built-in |
| SerializableUrl class | URL | Built-in |
| SerializableRegex class | RegExp | Built-in |
| Exception, Throwable | Error | Built-in |
POST Requests
Web routes with CSRF protection have limitations. See CSRF_LIMITATION.md for details.
Recommended approach for POST requests:
// Use API routes (no CSRF protection)
Route::post('/api/data', function() {
$data = request()->superjson();
return response()->superjson($result);
});
JavaScript Integration
Install the SuperJSON JavaScript library:
npm install superjson
import SuperJSON from 'superjson';
// Receiving data (always works)
const response = await fetch('/api/users');
const data = SuperJSON.parse(await response.text());
// data.created_at is a Date object
// Sending data (use API routes)
const payload = {
timestamp: new Date(),
bigNumber: BigInt('999999999999999999'),
tags: new Set(['frontend', 'api'])
};
await fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/superjson',
'Accept': 'application/superjson'
},
body: SuperJSON.stringify(payload)
});
Data Types Usage
BigInt
use SulimanBenhalim\LaravelSuperJson\DataTypes\BigInt;
$bigNumber = new BigInt('12345678901234567890');
$bigNumber->toString(); // "12345678901234567890"
$bigNumber->toInt(); // Converts to int if safe
Collections
use SulimanBenhalim\LaravelSuperJson\DataTypes\{SuperSet, SuperMap};
// Sets (unique values)
$tags = new SuperSet(['php', 'laravel', 'php']); // 'php' appears once
$tags->add('javascript');
$tags->has('php'); // true
$tags->remove('php');
// Maps (key-value pairs with any key type)
$config = new SuperMap([
['theme', 'dark'],
['timeout', 300],
[123, 'numeric key']
]);
$config->set('theme', 'light');
$theme = $config->get('theme'); // 'light'
URLs and RegExp
use SulimanBenhalim\LaravelSuperJson\DataTypes\{SerializableUrl, SerializableRegex};
$url = new SerializableUrl('https://example.com/path?q=search');
$url->getUrl(); // Returns parsed URL components
$pattern = new SerializableRegex('/user-(\d+)/', 'gi');
$pattern->getPattern(); // '/user-(\d+)/'
$pattern->getFlags(); // 'gi'
Custom Transformers
use SulimanBenhalim\LaravelSuperJson\Transformers\TypeTransformer;
class MoneyTransformer implements TypeTransformer
{
public function canTransform($value): bool
{
return $value instanceof Money;
}
public function transform($value): array
{
return [
'amount' => $value->getAmount(),
'currency' => $value->getCurrency(),
];
}
public function restore($value): Money
{
return new Money($value['amount'], $value['currency']);
}
public function getType(): string
{
return 'Money';
}
}
// Register in service provider
app('superjson')->registerTransformer(new MoneyTransformer());
Configuration
php artisan vendor:publish --tag=superjson-config
// config/superjson.php
return [
'transformers' => [
// Custom transformer classes
],
'options' => [
'preserve_zero_fraction' => true,
'unescaped_unicode' => true,
'throw_on_error' => true,
'max_depth' => 512,
],
'auto_routes' => [
'api/*', // Auto-apply to API routes
'superjson/*', // Custom route patterns
],
'type_mappings' => [
DateTime::class => 'Date',
DateTimeImmutable::class => 'Date',
'Carbon\Carbon' => 'Date',
],
'security' => [
'allow_class_restoration' => false,
'allowed_classes' => [],
'max_array_size' => 10000,
],
];
| Setting | Default | Description |
|---|---|---|
transformers |
Built-in types | Additional transformer classes |
preserve_zero_fraction |
true |
Keep .0 in numbers |
unescaped_unicode |
true |
Unicode handling |
throw_on_error |
true |
Error handling behavior |
max_depth |
512 |
Nesting limit |
auto_routes |
['api/*'] |
Routes for automatic middleware |
allow_class_restoration |
false |
Security: prevent class instantiation |
max_array_size |
10000 |
Array size limit |
Testing
composer test
Laravel Version Compatibility
| Laravel Version | Package Version |
|---|---|
| 11.x | 0.9.x-beta |
| 12.x | 0.9.x-beta |
Note: Version 1.0 will be released once CSRF limitations are resolved.
Security
If you discover any security issues, please email soliman.benhalim@gmail.com instead of using the issue tracker.
License
The MIT License (MIT). Please see License File for more information.