Back to all articles
Laravel Insights Dec 6, 2025 โˆ™ 1 min read

Debugging Made Easy with Spatie Ray: A Practical Guide

Learn how to use Spatie Ray for efficient debugging in Laravel applications with real-world examples.

A desktop setup illustrating the use of Spatie Ray for debugging a Laravel application.

Debugging Made Easy with Spatie Ray: A Practical Guide

Learn how to use Spatie Ray for efficient debugging in Laravel applications with real-world examples.

Debugging is an unavoidable part of software development. For years, PHP developers have relied on tools like var_dump(), print_r(), and Laravel's own dd() (die and dump) to inspect variables and understand application flow. While effective, these methods are disruptive. They halt code execution, clutter your browser or terminal, and need to be meticulously removed before committing code. This traditional "dump and die" workflow can be slow and cumbersome.

Enter Spatie Ray, a delightful desktop application that re-imagines the debugging experience. Instead of printing output to your screen and stopping your script, Ray provides a dedicated, clean window to receive all your debugging information. It allows your application to run uninterrupted while you observe its inner workings in real-time. From inspecting variables and tracking database queries to visualizing events and measuring performance, Ray transforms debugging from a chore into a streamlined and insightful process.

This guide will walk you through installing and using Spatie Ray in your Laravel projects. We’ll explore practical, real-world examples that demonstrate how Ray can help you fix problems faster and write better code.

What is Spatie Ray?

Ray is a paid desktop application (available for macOS, Windows, and Linux) created by the prolific team at Spatie. It acts as a central hub for debugging output from your PHP, Laravel, and even JavaScript applications. At its core, Ray is a beautifully designed server that listens for messages sent from your code via a simple ray() helper function.

Unlike traditional debugging tools that are tied to a single request, Ray provides a persistent timeline of events. This means you can see information from multiple requests, queue jobs, and Artisan commands all in one organized place.

Installation and Setup

Getting started with Ray involves two main steps: installing the desktop application and adding the companion package to your Laravel project.

Step 1: Install the Ray Desktop App

First, purchase and download the Ray application from the official website, myray.app. Install it just like any other desktop software. Once launched, Ray will be running in the background, ready to receive debugging information on its default port.

Step 2: Install the Laravel Package

Next, pull the spatie/laravel-ray package into your Laravel project using Composer.

composer require spatie/laravel-ray --dev

This package provides the ray() helper function and integrates deeply with Laravel to automatically report events like queries, mail, and more.

That’s it! With the app running and the package installed, you’re ready to start debugging.

Practical Debugging with Ray: Real-World Examples

The true power of Ray is revealed through its simple and intuitive API. The global ray() function is your gateway to sending almost anything to the Ray app.

1. Inspecting Variables and Objects

The most basic use case for any debugging tool is inspecting the value of a variable. Instead of dd($user), you can now use ray($user).

use App\Models\User;

public function show(int $id)
{
    $user = User::findOrFail($id);

    ray($user); // Send the user model to Ray

    return view('users.show', ['user' => $user]);
}

When this code executes, the entire $user model, complete with its attributes and relations, will appear in the Ray app without interrupting the page load. The output is beautifully formatted, collapsible, and easy to navigate. You can send multiple variables, and they will appear sequentially in Ray's timeline.

ray($user, $someOtherVariable, 'A simple string');

2. Tracking Database Queries

One of Ray's most powerful features for Laravel developers is its ability to automatically display database queries. You don’t have to do anything extra; just execute a query, and Ray will show you the full SQL, its bindings, and the execution time.

To enable this, simply call ray()->showQueries() at the start of your request, for example, in a service provider or middleware.

// In a controller method for targeted debugging
public function index()
{
    ray()->showQueries();

    $posts = Post::with('author')->where('published', true)->get();

    // ...
}

Ray will now display every query executed after this call. This is incredibly useful for spotting N+1 problems or analyzing the performance of complex queries. You can even create a dedicated QueryExecuted listener to send only slow queries to Ray.

3. Visualizing Events and Mailables

Ever wondered if an event was fired or if a mailable was sent correctly during a request? Ray makes this trivial.

To track events, use ray()->showEvents(). When an event like UserRegistered is dispatched, Ray will display the event class and its public properties.

For mail, you can send a mailable object directly to Ray to preview it.

use App\Mail\WelcomeEmail;
use App\Models\User;

$user = User::factory()->make();
$mailable = new WelcomeEmail($user);

ray($mailable);

Ray will render a beautiful preview of the email, allowing you to inspect its content, subject, and recipients without actually sending it.

4. Measuring Performance

Ray includes simple helpers for measuring performance and identifying bottlenecks. You can use the ray()->measure() method to wrap a block of code. Ray will display the execution time and memory usage of the enclosed code.

ray()->measure(function () {
    // A potentially slow operation
    sleep(2);
});

// Or measure memory usage
ray()->memory();
// ...some code...
ray()->memory();

This is a great way to get quick, real-time feedback on the performance of specific functions or operations without setting up a full-blown profiler.

Advanced Features

Ray is more than just a dd() replacement. It comes with a host of advanced features that can supercharge your workflow.

  • Pausing Execution: Need to inspect the state of your application at a specific point? Just drop in a ray()->pause() call. Your script will halt execution until you click "Continue" in the Ray app, giving you time to inspect other ray() outputs that came before it.
  • Color-Coding and Labels: You can organize your debugging output with colors and labels. ray($data)->green()->label('User Data') will display the output with a green highlight and a clear label, making it easy to find in a busy timeline.
  • Remote Debugging: Ray isn't limited to your local machine. You can configure it to send debugging information from a remote server (like staging or production) to your local Ray app via SSH. This is incredibly powerful for debugging issues that only occur in a production-like environment.
  • Screen Clearing: Use ray()->clearScreen() or ray()->newScreen() to clear the debugging timeline and start fresh for a new request, helping you focus on the task at hand.

Best Practices for Integrating Ray

To get the most out of Ray, consider integrating it thoughtfully into your workflow.

  1. Use it Everywhere: Ray is not just for web requests. Use it in Artisan commands, queued jobs, and Pest/PHPUnit tests.
  2. Keep it in Development: Since laravel-ray is installed as a dev dependency, the ray() function will not cause errors in production. However, it’s good practice to remove debugging calls before committing. Tools like Rector can be configured to automatically remove ray() calls.
  3. Create Snippets: Save time by creating code snippets for common Ray commands in your IDE, like ray($variable)->label('My Label').

Conclusion

Spatie Ray fundamentally changes the debugging experience for the better. By providing a dedicated, elegant, and non-disruptive interface for inspecting application behavior, it allows you to stay in the flow and solve problems more efficiently. Its deep integration with Laravel makes tracking queries, events, and other framework components effortless.

While dd() and var_dump() will always have their place, Ray offers a more sophisticated and enjoyable way to understand what your code is doing. If you're serious about improving your development workflow and productivity, investing in a tool like Ray is one of the best decisions you can make.


Related articles

Continue exploring Laravel insights and practical delivery strategies.

Laravel consulting

Need senior Laravel help for this topic?

Let's adapt these practices to your product and deliver the next milestone.