spatie/ray
Send debug output from any PHP app to Ray, Spatie’s desktop debugger. Inspect dumps, arrays, HTML, queries, and more with a consistent API across Laravel and vanilla PHP. Measure performance, pause execution, and keep fast feedback without cluttering logs.
Installation:
composer require spatie/ray
For Laravel, also install the service provider:
composer require spatie/laravel-ray
Configuration:
php artisan vendor:publish --provider="Spatie\Ray\RayServiceProvider" --tag="ray-config"
.env with your Ray server URL (e.g., RAY_SERVER_URL=http://localhost:8000).First Use Case:
Replace dd() or dump() with Ray’s ray() helper:
ray($user); // Inspects the $user object in the Ray app
Or use the facade:
use Spatie\Ray\Ray;
Ray::info('Debug message', ['key' => 'value']);
Debugging Variables:
ray($query->get(), 'Query results'); // Label + variable
ray(['user' => $user, 'posts' => $posts]); // Grouped data
Conditional Debugging:
if (config('app.debug')) {
ray($request->all(), 'Request payload');
}
Performance Measurement:
$start = microtime(true);
// ... code ...
ray(microtime(true) - $start, 'Execution time');
Query Inspection:
DB::enableQueryLog();
$results = DB::table('users')->get();
ray(DB::getQueryLog(), 'SQL queries');
Exception Handling:
try {
// Risky code
} catch (\Exception $e) {
ray($e, 'Exception details');
throw $e;
}
Middleware: Log requests/responses:
public function handle($request, Closure $next) {
ray($request->all(), 'Incoming request');
$response = $next($request);
ray($response->getContent(), 'Response');
return $response;
}
Commands: Debug CLI processes:
use Spatie\Ray\Ray;
Ray::command('user:import', function () {
ray('Starting import...');
// ...
});
Events: Inspect event payloads:
public function handle(Created $event) {
ray($event->user, 'New user created');
}
Testing: Debug tests without cluttering output:
ray($this->user, 'Test user data');
Performance Overhead:
ray() in tight loops or production. Use if (app()->environment('local')).RAY_ENABLED=false in .env.Large Payloads:
ray()->table() or ray()->json() to serialize efficiently.Circular References:
ray($user->toArray()) or ray($user)->without(['relationships']).Livewire/Blade:
ray($component)->asClass() to force class inspection.Configuration Conflicts:
RAY_SERVER_URL matches your local Ray server (default: http://localhost:8000).http://host.docker.internal:8000).Filtering Output: Use labels and tags to organize messages:
ray($user, 'User', ['type' => 'auth']);
Filter in Ray’s UI by label/tag.
Copying Data:
Right-click a variable in Ray to copy as JSON/array. For arrays, use ray($array)->copy() in code.
Expanding Payloads: Click the expand button in Ray to view nested structures (e.g., Eloquent collections).
Clipboard Integration:
Use ray($data)->clipboard() to auto-copy data to your system clipboard.
Custom Themes:
Configure themes in config/ray.php:
'theme' => 'dark', // 'light', 'dark', or 'auto'
Custom Handlers:
Extend Ray’s payload processing by overriding the Spatie\Ray\Ray class or using afterSendCallbacks:
Ray::afterSend(function ($payload) {
$payload['custom'] = 'metadata';
return $payload;
});
Rector Rules:
Remove ray() calls from production code using Ray’s Rector rule:
vendor/bin/rector process src --dry-run --config rector.php
PHPStan Rules:
Detect ray() calls in static analysis:
// rector.php
return static::configuredWithRules([
\Spatie\Ray\Rector\RemoveRayCallRector::class,
]);
Remote Debugging: For Docker/Laravel Forge, use the Ray Gateway to proxy requests to your local Ray server.
Log Context: Attach log context to Ray messages:
ray('Error', ['context' => ['user_id' => $user->id]]);
Keyboard Shortcuts:
Ctrl+Shift+R: Refresh Ray.Ctrl+F: Search messages.Ctrl+Click: Expand nested data.Markdown Support:
Use ray()->markdown('# Title') for formatted output.
Performance Tracing:
Use ray()->trace() to log execution time with context:
ray()->trace('User fetch', fn() => $user->load('posts'));
Environment-Specific Config:
Override config/ray.php per environment:
'enabled' => env('RAY_ENABLED', false),
How can I help you explore Laravel packages today?