Coming soon for Mac, Windows and Linux

Keep an eye on your code. Let your AI keep an eye too.

Gaze is a free desktop debugger for PHP, Laravel and JavaScript.

Get launch news

Free for Mac, Windows and Linux · PHP 8.2+ · Laravel 12 and 13 · Node 20.19+

The Gaze window, half in its light theme and half in its dark theme: a Laravel request with its queries grouped under it, a paused PHP process waiting for Continue, and a dumped Order model open in the inspector
OrderController.php
$order = Order::findOrFail($id);
$order->load('items.product');

// shows up in Gaze, with this file and line
gaze($order)->label('order');

Your whole stack. One window.

The same gaze() call in PHP and JavaScript, on the server and in the browser.

  • Laravel
  • PHP
  • JavaScript
  • Node.js
  • Next.js
  • Vue
  • React
  • Svelte

Also Express, Fastify, Hono, NestJS, Bun, Deno and Vite, with SQL from Prisma, Drizzle, pg, mysql2, postgres and better-sqlite3.

The window

Everything your code says. In one place.

Dumps, queries, logs, mail and errors from every app you run, in one window. Here is what is where.

The Gaze window: Live and search in the toolbar, sources and screens in the sidebar, a paused process banner, a Laravel request with N+1 and duplicate counts, the inspector with Open in PhpStorm, and the status bar
  1. Live feed; pause it to read in peace
  2. Search with tokens like type:query and file:
  3. Sources: every app and machine, merged or one at a time
  4. Screens: a clean feed for the bug you're chasing
  5. Paused processes, waiting for Continue
  6. Traces with their counts: queries, N+1, duplicates
  7. Inspector: value, raw data, origin and context
  8. Status bar: where Gaze listens and what it holds
PHP, Laravel, JavaScript

One call. From anywhere in your code.

Install the client for your stack and call gaze(). Each value lands with the file and line it came from, one click from your editor.

Gaze showing a Laravel POST /checkout request that failed with a QueryException: its queries, a slow query, the dispatched job and the exception with the code around line 84
Laravel
composer require thewonderjoy/gaze-laravel

gaze($order)->label('order');
User::where('active', true)->gaze()->get();
@gaze($order)

Laravel

Queries, logs, mail, jobs and exceptions arrive on their own, grouped by request. An exception brings the code around its line and the queries that ran before it.

Front end to back end

From fetch to query.

Turn on network capture in gaze-js and each fetch from your Vue, React or Svelte app carries a trace header. The Laravel or Node request it starts links back to that call, with its own queries, logs and exceptions.

  • Laravel and Node back ends
  • Calls to your own origin link on their own
  • An API elsewhere? Add it to propagate
Traces

Requests, not a pile of dumps.

Everything one request does lands under it, with a summary on top: status, time, queries and anything that looks wrong. Jobs, artisan commands and tests get the same.

Gaze's list view: GET /orders/42 with 23 queries, N+1 and 12 duplicates, and the N+1 query open in the inspector with advice to eager-load the relation and the list of its 12 runs

N+1, found for you.

Repeated queries fold into one row that lists every run, with the line to fix and a hint to eager-load.

Where the time went.

The timeline draws every query, view and HTTP call from when it started. Press T to switch.

Follow the thread.

A queued job shows the request that dispatched it. A fetch in the browser links to the API request it started.

Pause

Stop the script. Look around.

gaze()->pause() holds your code on that line until you press Continue in Gaze. Read everything it sent so far, then let it run, or stop it right there.

  • PHP and JavaScript
  • In a request, a job or a script
  • See how long it has been waiting
CheckoutController.php
$order = $this->orders->fromCart($cart);

gaze()->pause();

$intent = $this->stripe->charge($order);

1 PHP process paused · POST /checkout at CheckoutController.php:88 · 0:00

Try it: the bar works like the one in the app.

Safe by default

Leave a call in. Nothing breaks.

Everyone ships a stray dump sooner or later. Gaze is built for that day.

Off in production.

When APP_ENV is production, gaze() turns into a no-op and nothing is sent. JavaScript builds swap in a stand-in that sends nothing.

A forgotten call does nothing.

gaze_dd() doesn't exit, @gaze renders nothing and ->gaze() passes the value straight through.

Secrets stay masked.

Passwords, tokens, cookies and .env secrets are replaced with a mask before anything leaves your app.

Clean up in one command.

php artisan gaze:clean removes leftover gaze() and gaze_dd() calls before you deploy.

Coming from Ray

A free alternative to Ray.

Your ray() calls already work. Gaze listens on Ray's port, 23517, so calls from spatie/ray, spatie/laravel-ray and node-ray show up with no changes, and Gaze itself is free. Move to gaze() whenever you like; the method names are the same.

Ray is a product of Spatie. Gaze is not affiliated with or endorsed by Spatie.

OrderController.php
ray($order)->green();

Shows up in Gaze either way

AI agents

Let your agent look too.

Gaze answers AI coding agents over MCP. Your agent can read the latest request, or the last one that failed, with its queries, logs and exceptions, and search what your apps sent.

claude mcp add --transport http gaze http://127.0.0.1:23517/mcp
  • Read-only
  • Web pages can't reach it
  • One switch in Settings turns it off
Gaze's Settings, Connection tab: the MCP server switch, its address http://127.0.0.1:23517/mcp, the claude mcp add command, and the note that agents get read-only access to requests, traces and entries
The details

Small things. For long sessions.

Find anything, from the keyboard.

Search with type:query, file:OrderController or a phrase in quotes, and save it to the sidebar. Every action has a key.

Gaze's command palette open over the feed, listing commands with their shortcuts
Open in…

Your editor, at the line.

PhpStorm, VS Code, Cursor, Windsurf, Zed or Sublime Text.

checkout-bug

Screens.

Start a clean feed for the bug you're chasing. The rest stays one click away.

Seven themes.

Each in light and dark, and every one keeps text easy to read.

gaze:doctor

Sail, Docker, WSL2.

Found on their own. If not, the doctor prints the .env lines to add.

<table>

More than dumps.

Tables, JSON, HTML, Markdown, Mermaid, mail and images, each shown the way it should look.

Questions

Questions, answered.

What is Gaze?

Gaze is a desktop app that shows what your code sends it while you work. Call gaze($value) in PHP, Laravel or JavaScript and the value appears in the Gaze window with the file and line it came from. Queries, logs, mail and exceptions arrive grouped by the request, job, command or test that caused them.

When can I download Gaze?

Gaze is coming soon for Mac, Windows and Linux. Ask for launch news and we will email you the day it is out.

Which systems does Gaze run on?

Mac, Windows and Linux. The apps that send to it can run on the same computer, in Docker or Sail, or in WSL2.

Which versions of PHP, Laravel and Node does Gaze support?

gaze-php and gaze-laravel need PHP 8.2 or later, and gaze-laravel supports Laravel 12 and 13. gaze-js runs on Node 20.19 or later (22.12 recommended), Bun, Deno, browsers, workers and edge runtimes.

How does Gaze find N+1 queries?

gaze-laravel and gaze-js watch every query in a request. When the same query runs again and again with different values, Gaze folds the runs into one N+1 row, lists every execution and points at the line that ran them, with a hint to eager-load the relation.

Does Gaze work with Sail, Docker and WSL?

Yes. gaze-laravel finds Gaze from Docker, Sail and WSL2 on its own, and Herd or php artisan serve need nothing at all. If it can't connect, php artisan gaze:doctor says why and prints the exact .env lines to add.

Can Gaze link my front end to my back end?

Yes. Turn on network capture in gaze-js and each fetch and XHR from the browser carries a traceparent header. gaze-laravel, or gaze-js on Node, links the request it starts back to that call. Calls to your own origin link on their own; for an API on another origin, add it to propagate and allow the traceparent header in CORS.

Which JavaScript frameworks does Gaze cover?

Started with gaze-js run, Node servers get one group per request in Express, Fastify, Hono, NestJS, Next.js and plain node:http, with SQL from pg, mysql2, postgres and better-sqlite3, so Prisma, Drizzle, Kysely and Knex too. There is a Vite plugin for browser code and adapters for Vue, React and Svelte.

What happens if I forget a gaze() call in production?

Nothing. Gaze is off when APP_ENV is production (NODE_ENV for JavaScript): gaze() becomes a no-op, gaze_dd() doesn't exit, and production bundles get a tiny stand-in that sends nothing. Before you deploy, php artisan gaze:clean removes leftover calls.

Does Gaze send my data anywhere?

No. Your apps send to Gaze on your own computer, and there is no account. Passwords, tokens, cookies and .env secrets are masked before they leave your app.

Which editors can Gaze open files in?

PhpStorm, VS Code, Cursor, Windsurf, Zed and Sublime Text, at the exact file and line, or your system default.

Can my AI coding agent read what Gaze receives?

Yes. Gaze answers AI agents over MCP at http://127.0.0.1:23517/mcp. Agents can read the latest request or the last one that failed with its queries, logs and exceptions, list traces and search entries. It is read-only, web pages cannot reach it, and you can turn it off in Settings.

Is Gaze free?

Yes. Gaze is free on Mac, Windows and Linux, with no account to create. The client libraries, gaze-php, gaze-laravel and gaze-js, are MIT licensed.

The Gaze app icon: two white angle brackets around an indigo dot on a dark tile

Keep an eye out.

Gaze is free and coming soon for Mac, Windows and Linux. Get launch news and we'll email you the day it's ready.

Get launch news

PHP 8.2+ · Laravel 12 and 13 · Node 20.19+