PHPackages                             corentinbtmps/laravel-vitals - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. corentinbtmps/laravel-vitals

ActiveLibrary[Testing &amp; Quality](/categories/testing)

corentinbtmps/laravel-vitals
============================

GTMetrix-style Lighthouse audits combined with backend telemetry and host-app source pointers, for Laravel 11/12/13.

v1.0.0(2w ago)40MITPHPPHP ^8.2CI passing

Since May 22Pushed 2w ago1 watchersCompare

[ Source](https://github.com/corentinbtmps/laravel-vitals)[ Packagist](https://packagist.org/packages/corentinbtmps/laravel-vitals)[ RSS](/packages/corentinbtmps-laravel-vitals/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (18)Versions (2)Used By (0)

 [![Laravel Vitals](resources/svg/logo.svg)](resources/svg/logo.svg)

[![CI](https://github.com/corentinbtmps/laravel-vitals/actions/workflows/ci.yml/badge.svg)](https://github.com/corentinbtmps/laravel-vitals/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/bcac99fabf9ae3acd63a7613941dcf6feee655830ebbb1beaca7f18332e79a0c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f636f72656e74696e62746d70732f6c61726176656c2d766974616c732e737667)](https://packagist.org/packages/corentinbtmps/laravel-vitals)[![License](https://camo.githubusercontent.com/7d730e15fcde317778aa3a8fc39521c345f207a11ab5cefbe1c3619b235571cf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f636f72656e74696e62746d70732f6c61726176656c2d766974616c732e737667)](LICENSE.md)

Laravel Vitals
==============

[](#laravel-vitals)

**Performance auditing, Real User Monitoring, and actionable recommendations — all inside your Laravel app.**

 [![Laravel Vitals — Overview dashboard](docs/screenshots/overview-light.png)](docs/screenshots/overview-light.png)
 *Overview dashboard — onboarding progress, lens cards with sparklines, recent activity, active alerts*

---

Table of contents
-----------------

[](#table-of-contents)

- [What is Laravel Vitals](#what-is-laravel-vitals)
- [Why Laravel Vitals](#why-laravel-vitals)
- [Requirements](#requirements)
- [Installation](#installation)
- [Quick start](#quick-start)
- [Architecture](#architecture)
- [Features](#features)
    - [Lighthouse audits — three drivers](#lighthouse-audits--three-drivers)
    - [Backend telemetry](#backend-telemetry)
    - [Source code references](#source-code-references)
    - [Real User Monitoring](#real-user-monitoring)
    - [Database query baselines](#database-query-baselines)
    - [Performance budgets](#performance-budgets)
    - [Dashboard](#dashboard)
    - [Issues page](#issues-page)
    - [Learn knowledge base](#learn-knowledge-base)
    - [JSON API](#json-api)
    - [CI integration](#ci-integration)
    - [Slack notifications](#slack-notifications)
    - [Public endpoints](#public-endpoints)
    - [Boost and Claude Code integration](#boost-and-claude-code-integration)
- [Configuration](#configuration)
- [Artisan commands](#artisan-commands)
- [Privacy](#privacy)
- [Performance impact](#performance-impact)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)

---

What is Laravel Vitals
----------------------

[](#what-is-laravel-vitals)

Laravel Vitals runs Google Lighthouse against your own pages, captures what your server was doing at that exact moment — queries, memory, N+1 problems — and points directly at the lines of code responsible. Everything lands in a dashboard at `/vitals` that any team member can read and act on. Real User Monitoring is opt-in with one Blade directive. Your data stays in your own database — no SaaS, no per-seat billing.

---

Why Laravel Vitals
------------------

[](#why-laravel-vitals)

CapabilityGTMetrix / PageSpeedLaravel VitalsLighthouse scores (Performance, Accessibility, SEO, Best Practices)✓**✓**Backend telemetry — queries, memory, N+1, cache✗**✓**Source code references — exact file and line in your app✗**✓**Real User Monitoring — self-hosted, no PIIpaid / ✗**✓**Performance budgets with CI exit codes✗**✓**GitHub PR auto-comments with score table✗**✓**Self-hosted — your data stays yours✗**✓**---

Requirements
------------

[](#requirements)

- PHP 8.2 or higher
- Laravel 11, 12, or 13
- Livewire 4 and Flux Free 2 (installed automatically by Composer)
- **Local driver:** Node 18+ and `npm install -g lighthouse`
- **Playwright driver:** Node 18+ and `npm install playwright playwright-lighthouse` in your project
- **PageSpeed driver:** a free [Google PageSpeed Insights API key](https://developers.google.com/speed/docs/insights/v5/get-started)

The `auto` driver (default) tries `local` → `playwright` → `pagespeed` in order. If your server has Node and the lighthouse CLI, no extra setup is needed.

---

Installation
------------

[](#installation)

```
composer require corentinbtmps/laravel-vitals
php artisan vendor:publish --tag=vitals-config
php artisan migrate
php artisan vitals:install
```

Add `@vitalsRum` to your main layout's `` to enable Real User Monitoring:

```

    @vitalsRum

```

Verify the setup:

```
php artisan vitals:doctor
```

---

Quick start
-----------

[](#quick-start)

Declare a URL in `config/vitals.php`:

```
'urls' => ['home' => '/'],
```

Run your first audit:

```
php artisan vitals:audit home --sync
```

Visit `/vitals`.

That's it. You now have a Lighthouse score, backend telemetry, and a list of recommendations with file/line references in your own source code.

---

Architecture
------------

[](#architecture)

 [![Laravel Vitals architecture diagram](docs/screenshots/architecture.svg)](docs/screenshots/architecture.svg)

1. **Declare URLs** in `config/vitals.php` as `'label' => '/path'` pairs. Run `vitals:audit` manually, on a schedule, or from CI.
2. **Audit starts.** The package signs an `X-Vitals-Audit-Id` header with your `APP_KEY` and spawns Lighthouse (local Node, Playwright, or Google PageSpeed API depending on your driver).
3. **Backend telemetry.** While Lighthouse navigates the page, your own middleware detects the signed header and records: query count, total query time, N+1 suspicion, peak memory, views rendered, jobs dispatched, and cache hits/misses.
4. **Lighthouse result.** Scores arrive (0–100) alongside raw metric values: LCP, INP, CLS, TTFB, FCP, TBT, Speed Index.
5. **Code analysis.** Static analyzers scan your Blade views, Vite config, and `composer.json` to attach exact file:line references to each Lighthouse finding. Everything is stored and surfaced at `/vitals`. If a budget threshold is exceeded or a regression is detected, a Slack message or email fires automatically.

---

Features
--------

[](#features)

### SEO checks (22 Google-aligned)

[](#seo-checks-22-google-aligned)

Laravel Vitals ships its own SEO check engine that runs alongside every Lighthouse audit. Unlike Lighthouse's built-in SEO score (which covers ~8 signals), the custom checks cover 22 areas — every one a Google-documented ranking signal, no Yoast-style heuristics:

CategoryChecksConfiguration (3)noindex directive, nofollow, robots.txt indexabilityContent (5)H1 uniqueness, HTTPS resources, image alt text, broken links (samples ≤ 30), broken imagesMeta (7)Meta description, title length, Open Graph image, HTML lang, canonical URL, JSON-LD structured data, invalid head elementsPerformance (7)TTFB ≤ 600ms, HTTP status code, HTML size, image size, JS bundle size, CSS size, gzip/Brotli compressionResults appear on **`/vitals/audits/{id}/seo`** (per-audit deep view with actual vs expected values, hint text, and links to Google documentation) and on the **`/vitals/seo`** cross-URL page (aggregated score table, top failing checks by category, period filter).

 [![SEO — average score, per-URL table, top failing checks with category filter](docs/screenshots/seo-light.png)](docs/screenshots/seo-light.png)
 *SEO — average score across URLs, per-URL custom + Lighthouse scores, top failing checks filtered by category*

 [![Per-audit SEO deep view — checks grouped by Configuration / Content / Meta / Performance](docs/screenshots/audit-seo-light.png)](docs/screenshots/audit-seo-light.png)
 *Per-audit SEO deep view — each check grouped by category, with actual vs expected values and direct links to Google documentation*

The combined `vitals_seo_score` blends Lighthouse's SEO score (50%) with the weighted pass rate of all custom checks (50%), producing a stricter 0–100 score.

```
// config/vitals.php
'seo' => [
    'enabled'         => env('VITALS_SEO_ENABLED', true),
    'thresholds'      => ['title_max_chars' => 60, 'ttfb_ms' => 600],
    'disabled_checks' => [],  // e.g. ['broken-links', 'css-size']
],
```

### Lighthouse audits — three drivers

[](#lighthouse-audits--three-drivers)

Lighthouse simulates a page load under realistic mobile conditions and scores Performance, Accessibility, Best Practices, and SEO from 0 to 100.

DriverRequiresBest for`local`Node 18+ + `lighthouse` CLIDev machines and CI with Node`playwright`Node 18+ + `playwright` + `playwright-lighthouse`Docker-based CI`pagespeed`Google API key (`VITALS_PAGESPEED_API_KEY`)Public URLs, no Node needed`auto`Falls back through the aboveDefault — works in most environmentsThe `local` and `playwright` drivers work behind authentication. The `pagespeed` driver requires a publicly reachable URL and cannot capture backend telemetry.

```
php artisan vitals:audit home --driver=local --device=mobile
php artisan vitals:audit --all --sync   # all URLs, synchronous (CI-friendly)
```

---

### Backend telemetry

[](#backend-telemetry)

When Lighthouse loads a page, the package captures a server-side snapshot: query count, total query time, unique queries, N+1 suspect flag (triggered when queries\_count / queries\_unique ≥ 10), peak memory, views rendered, jobs dispatched, cache hits/misses, and any slow queries that exceed the configured threshold (default: 50ms).

When N+1 queries are detected, the package also stores up to 200 normalized SQL patterns per request with the exact PHP file and line that triggered each query (skipping vendor and package frames to always point at your own code). The audit detail and issue detail pages surface the top 3 repeated patterns with occurrence counts and caller locations.

This answers questions that Lighthouse alone cannot: "Why is our LCP slow — is it the database?" or "Which exact line in my controller is causing 42 repeated queries?"

By default, telemetry is only captured during audit runs — zero overhead for real visitors. Set `telemetry.always_capture = true` to sample a configurable percentage of all requests (default 5%), similar to how Laravel Pulse works.

---

### Source code references

[](#source-code-references)

This is the key differentiator. When Lighthouse flags "render-blocking resources" or "unused JavaScript", the package shows you the exact file and line in your codebase that caused it.

```
Recommendation: Eliminate render-blocking resources
Source: resources/views/layouts/app.blade.php  line 12

  Hint: Use @vite([...]) to bundle and version this asset, or add defer/async.

```

Seven analyzers scan your project: Blade asset tags, image tags, Laravel config settings (missing `config:cache`, debug mode in production), Composer packages, Vite config, Blade view patterns, and `.env` settings.

---

### Real User Monitoring

[](#real-user-monitoring)

Add `@vitalsRum` to your layout's `` to collect Core Web Vitals (LCP, INP, CLS, TTFB, FCP) from real visitors. Beacons are sent via `sendBeacon` after page load — no impact on performance. Results appear at `/vitals/rum`.

**Privacy by design:** no IP addresses, no cookies, no session identifiers. Only metric values, URL path, device type, connection hint, and user-agent are stored. See [Privacy](#privacy) for the full list.

---

### Database query baselines

[](#database-query-baselines)

 [![Database queries — per-route Typical / Worst case query counts and times](docs/screenshots/queries-light.png)](docs/screenshots/queries-light.png)
 *Queries — per-route stats with N+1 badges, plain-language Typical / Worst case labels, and memory-hungry route ranking*

The `/vitals/queries` page answers a question most teams cannot: "Did this recent deployment slow down the database on route X?"

For each route with telemetry data you get the number of samples, **Typical** (75th percentile) and **Worst case** (95th percentile) for both query count and query time. Routes are compared to the previous equivalent period — if you are looking at 7 days, it compares to the 7 days before that. A route is flagged with a regression badge when its current Typical query count is more than double the baseline. Any route whose audits have triggered N+1 detection gets a red **N+1** badge inline with its name.

Click any route to expand a per-route panel below the table with:

- **Affected URLs** — every URL that hit this route in the period, linking back to URL detail.
- **Recent audits** — last five audits with this route name, with their queries count and time.
- **Repeated SQL patterns** — the top SQL patterns the N+1 detector caught on this route, with occurrence count and the exact `file:line` caller (clickable, opens in your IDE).

A "Memory-hungry routes" panel below ranks the top 5 routes by typical peak memory — useful for catching routes that spike to 256 MB on 25% of requests before they cause production incidents.

---

### Performance budgets

[](#performance-budgets)

Set limits on any metric. When an audit exceeds a limit, an alert fires.

```
// config/vitals.php
'budgets' => [
    'lcp_ms'            => ['warning' => 2500, 'critical' => 4000],
    'score_performance' => ['warning' => 90,   'critical' => 70],
    // ... per_url overrides available
],
```

Use `--fail-on-budget` in CI to get non-zero exit codes (1 = warning, 2 = critical):

```
php artisan vitals:audit --all --sync --fail-on-budget --format=junit > results.xml
```

---

### Dashboard

[](#dashboard)

A Livewire application at `/vitals` — no asset compilation required in your app.

 [![Audit detail — score gauges and Core Web Vitals breakdown](docs/screenshots/audit-detail-light.png)](docs/screenshots/audit-detail-light.png)
 *Audit detail — Performance / Accessibility / Best Practices / SEO score gauges with delta vs previous audit, Core Web Vitals cards, front-end ↔ back-end timing breakdown*

Eight top-level pages: Overview · URLs · Issues · SEO · RUM · Queries · Learn · Budgets. A built-in Cmd+K spotlight searches across URLs, audits, and recommendations anywhere in the dashboard.

**Access control:** available in `local` by default. To allow access in production, define the `viewVitals` gate:

```
use LaravelVitals\Facades\Vitals;

Vitals::authorize(fn ($user) => $user?->is_admin ?? false);
```

---

### Issues page

[](#issues-page)

 [![Issues — All recommendations with severity-tinted cards](docs/screenshots/issues-light.png)](docs/screenshots/issues-light.png)
 *Issues — All recommendations aggregated across audits, each card tinted by severity (amber / rose / sky) with title color matching*

`/vitals/issues` has two tabs. **Top issues** shows cross-URL quick wins, URLs that are currently worsening or improving, and third-party script cost breakdowns. **All recommendations** aggregates every recommendation across all audits, sorted by frequency — making it easy to find the one fix that would improve the most pages at once.

Each row is a severity-tinted card: amber for warning, rose for critical, sky for info. The title link inherits the card's severity color so the page reads at a glance — no need to parse small badges. Click any title (or the trailing `N occurrences` button) to land on `/vitals/issues/{audit_key}` — a deep view that shows every occurrence grouped by URL, with the exact file and line where the issue originates in your code. For N+1 queries, this page lists the top 3 repeated SQL patterns with occurrence counts and caller location.

Each recommendation includes severity (info / warning / critical), category (Performance, Accessibility, Best Practices, SEO), the source code reference (file + line), a one-sentence fix hint, and links to the relevant web.dev article and Laravel documentation. The package covers Lighthouse findings, Laravel-specific issues (missing `config:cache`, debug mode in production, sync queue, disabled OPcache), and backend signals (N+1 queries with SQL attribution, slow queries, large payloads).

---

### Learn knowledge base

[](#learn-knowledge-base)

 [![Learn — category tiles and severity-tinted recommendation cards](docs/screenshots/learn-light.png)](docs/screenshots/learn-light.png)
 *Learn — 73 issue types explained with web.dev / Laravel doc links, severity-tinted cards, and Recommended / Avoid code samples*

`/vitals/learn` is a browsable knowledge base of every detectable issue, grouped by category (Performance, Accessibility, Best Practices, SEO). Each entry covers what causes the finding, its impact, and how to fix it — with links to web.dev and the relevant Laravel documentation, plus side-by-side **Recommended** / **Avoid** code snippets when relevant. The category tiles at the top double as filters and show the active-in-your-app count per category, so you can spot which class of issues currently bites your project hardest.

---

### JSON API

[](#json-api)

A read-only JSON API at `/vitals/api/v1`, protected by the same `viewVitals` gate. No separate API tokens required — the session cookie is sufficient for CI scripts making authenticated requests. Intended for custom dashboards, CI scripts, and third-party integrations.

EndpointReturns`GET /vitals/api/v1/audits`Paginated audit list`GET /vitals/api/v1/audits/{id}`Single audit with scores, metrics, recommendations`GET /vitals/api/v1/urls`All configured URLs`GET /vitals/api/v1/urls/{id}/latest`Most recent audit for one URL`GET /vitals/api/v1/recommendations`All stored recommendationsQuery parameters: `?page=N&per_page=M` (default 25, max 100), `?since=YYYY-MM-DD&until=YYYY-MM-DD`.

```
curl -s https://yourapp.com/vitals/api/v1/urls/1/latest \
  -H "Accept: application/json"
```

---

### CI integration

[](#ci-integration)

**GitHub Action** — audits your preview deployment and posts a score comparison table as a PR comment. Your team sees the performance impact before merging, without running any manual checks.

```
# .github/workflows/pr-perf.yml
- uses: corentinbtmps/laravel-vitals/.github/actions/vitals-pr-comment@v1.0.0
  with:
    preview-url: ${{ vars.PREVIEW_URL }}
    base-url: https://your-production-app.com
    github-token: ${{ secrets.GITHUB_TOKEN }}
    fail-on-regression: 'true'  # exit 1 when score drops > regression-threshold
```

Available inputs: `preview-url` (required), `base-url`, `github-token` (required), `fail-on-regression` (default false), `regression-threshold` (default 5 points), `devices` (default `mobile`; accepts `mobile,desktop`).

**Pre-commit hook** — runs `vitals:doctor` before every `git commit` and blocks the commit if any check fails (missing migration, broken asset, mis-configured notification):

```
php artisan vitals:install-hook             # install (or --type=pre-push for push hook)
php artisan vitals:install-hook --uninstall # remove (restores previous hook from backup)
```

---

### Slack notifications

[](#slack-notifications)

Set `VITALS_NOTIFICATIONS_SLACK_WEBHOOK` in `.env`. Each completed audit that triggers an alert posts a message to your channel. Budget violations and regression alerts are posted as replies in the same thread — the Slack message timestamp is stored so follow-ups always find the right thread.

```
VITALS_NOTIFICATIONS_SLACK_WEBHOOK=https://hooks.slack.com/services/...
VITALS_NOTIFICATIONS_MAIL_TO=team@yourcompany.com
```

Notification triggers: `budget_violation` (on by default), `regression` (on, 10% threshold), `weekly_digest` (on), `audit_completed` (off — too noisy for most teams). Supported channels: `mail`, `slack`, `database`.

Add these to your scheduler:

```
Schedule::command('vitals:digest:send')->weekly();
Schedule::command('vitals:check-regressions')->daily();
```

---

### Public endpoints

[](#public-endpoints)

**Health check** — `GET /vitals/health` returns database status, driver availability, queue status, and telemetry buffer state. HTTP 200 = all checks pass; 503 = something failed. No auth required — suitable for Uptime Robot and similar monitors.

**Status page** — `GET /vitals/status` is an opt-in public page showing uptime %, Core Web Vitals distribution, and recent incidents. Enable it in `config/vitals.php`:

```
'status' => ['enabled' => true, 'title' => 'My App Status'],
```

**Self-monitoring** — `vitals:self-check` reports Vitals table sizes and the 10 slowest telemetry captures. Schedule it hourly to catch overhead early.

---

### Boost and Claude Code integration

[](#boost-and-claude-code-integration)

`php artisan vitals:install` writes two context files into your project:

- `.ai/guidelines/vitals.blade.php` — used by Laravel Boost and compatible AI tools
- `.claude/skills/laravel-vitals/SKILL.md` — used by Claude Code (Anthropic's CLI)

These help AI coding assistants generate correct code when you ask them to add recommendations or RUM metrics. Re-publish after updating the package with `php artisan vitals:boost:install --force`.

---

Configuration
-------------

[](#configuration)

Full annotated source: `config/vitals.php`. The most useful keys:

KeyDefaultWhat it controls`driver``auto`Lighthouse driver. `auto` tries local → playwright → pagespeed.`urls``[]`Monitored URLs as `['label' => '/path']`.`telemetry.always_capture``false`Set `true` to sample all requests, not just audits.`telemetry.slow_query_threshold_ms``50`Queries slower than this are stored individually.`budgets.*`see configWarning/critical thresholds per metric. `per_url` allows per-URL overrides.`rum.sample_rate``1.0`Fraction of page loads that send a RUM beacon (0.05–0.1 for high-traffic).`notifications.channels``['mail']`Add `'slack'` or `'database'` as needed.`ui.editor``null`Editor preset — see "Open in editor" section below.`ui.editor_url_template``null`Custom URL scheme override — see "Open in editor" section below.`status.enabled``false`Opt-in public status page at `/vitals/status`.`retention.days``90`Audit and RUM retention. RUM has its own `rum.retention_days` (also 90 days).The UI is available in English, French, German, and Spanish — follows `app()->getLocale()`.

### Open in editor

[](#open-in-editor)

Add `VITALS_EDITOR=vscode` (or `phpstorm`, `cursor`, `sublime`, `atom`, `textmate`, `idea`, `zed`, `nova`, `macvim`, `emacs`) to your `.env` and every file:line reference in the dashboard becomes a clickable link that jumps to the right file and line in your IDE — the same UX as Spatie Ignition's error pages.

For a custom URL scheme not in the preset list, set `VITALS_EDITOR_URL_TEMPLATE` directly: `myeditor://{path}:{line}`. The custom template overrides the preset.

> Future versions may auto-detect the editor from the request context.

---

Artisan commands
----------------

[](#artisan-commands)

CommandWhat it does`vitals:audit {label}`Audit one URL`vitals:audit --all`Audit all URLs (queued batch)`vitals:audit --all --sync`Audit all URLs synchronously`vitals:demo`Seed fictional data for exploration`vitals:doctor`Run diagnostic checks`vitals:install`Publish Boost and Claude Code skill files`vitals:install-hook`Install a git pre-commit hook`vitals:discover --routes`List candidate URLs from your routes`vitals:discover --sitemap=URL`List candidate URLs from a sitemap`vitals:check-regressions`Compare latest audits to the 7-day baseline`vitals:digest:send`Send a weekly summary`vitals:purge --demo`Remove demo data`vitals:purge`Remove all Vitals data (confirmation required)`vitals:boost:install`Re-publish Boost / Claude skill files`vitals:boost:diff`Check if installed AI files differ from package`vitals:self-check`Check table sizes and slow telemetry captures**Key `vitals:audit` options:**

OptionDescription`--device=mobile|desktop`Device profile (default: mobile)`--driver=local|playwright|pagespeed`Override configured driver`--sync`Run synchronously instead of queuing`--fail-on-budget`Exit 1 (warning) or 2 (critical) on budget violations`--format=table|json|junit`Output format---

Privacy
-------

[](#privacy)

**What RUM collects:** metric name and value, rating (good/needs-improvement/poor), URL path, device type, connection hint, navigation type, user-agent string.

**What RUM does NOT collect:** IP addresses, cookies, session identifiers, user IDs, geolocation, or any fingerprint.

Backend telemetry records server-side performance metrics, not user behavior. It is only stored during audit runs unless `telemetry.always_capture` is enabled.

**Retention:** audits and RUM events default to 90 days. Configure via `retention.days` and `rum.retention_days`. Schedule `model:prune` daily to apply it:

```
$schedule->command('model:prune', ['--model' => [
    \LaravelVitals\Models\Audit::class,
    \LaravelVitals\Models\Recommendation::class,
    \LaravelVitals\Models\BackendTelemetry::class,
    \LaravelVitals\Models\RumEvent::class,
]])->daily();
```

Because no PII is collected in RUM beacons, this data typically does not require GDPR consent mechanisms. Consult your legal team for your jurisdiction.

---

Performance impact
------------------

[](#performance-impact)

**Middleware:** `CaptureVitalsTelemetry` returns immediately on every request that does not carry the `X-Vitals-Audit-Id` header. The fast-path overhead is sub-microsecond.

**RUM script:** ~4.25 kB gzipped, loaded with `defer`, sends beacons only after full page load via `sendBeacon`.

**Dashboard assets:** served by dedicated package routes with long-lived cache headers. Never loaded for non-dashboard routes.

---

Troubleshooting
---------------

[](#troubleshooting)

**1. "URL \[home\] not found in config or database"**Declare it in `config/vitals.php` first: `'urls' => ['home' => '/']`, then re-run the audit.

**2. Lighthouse fails with a Chrome error in Docker / Linux**Add `--no-sandbox` to `chrome_flags`:

```
'drivers' => ['local' => ['chrome_flags' => ['--headless', '--no-sandbox']]],
```

**3. Dashboard shows "Access Denied"**Define the `viewVitals` gate in `AppServiceProvider`:

```
Vitals::authorize(fn ($user) => $user?->is_admin ?? false);
```

**4. RUM data not appearing**Verify `@vitalsRum` is in `` and `VITALS_RUM_ENABLED=true` is set. Check the browser network tab for a POST to `/vitals/rum/ingest`.

**5. `vitals:doctor` shows failing checks**Read the output — each line includes a remediation hint. Common fixes: `php artisan migrate` (unpublished migrations), `Add VITALS_NOTIFICATIONS_MAIL_TO` (mail notifications configured without a recipient).

---

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions, code conventions, and how to add a new recommendation or RUM metric.

---

License
-------

[](#license)

Laravel Vitals is open-source software released under the [MIT license](LICENSE.md).

Built with: [Livewire](https://livewire.laravel.com), [Flux](https://fluxui.dev), [Google Lighthouse](https://developer.chrome.com/docs/lighthouse/overview/), [web-vitals](https://github.com/GoogleChrome/web-vitals), [spatie/laravel-searchable](https://github.com/spatie/laravel-searchable), [spatie/laravel-onboard](https://github.com/spatie/laravel-onboard).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance96

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

18d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2014c62facacb2c7f24e2364b7fe46fb8852f8b383d7e73d9d724a2ae980170e?d=identicon)[corentinbtmps](/maintainers/corentinbtmps)

---

Top Contributors

[![corentinbtmps](https://avatars.githubusercontent.com/u/77066685?v=4)](https://github.com/corentinbtmps "corentinbtmps (219 commits)")

---

Tags

auditcore-web-vitalslaravellighthousepagespeed-insightsperformanceseolaravelperformanceAuditlighthousePageSpeedcore-web-vitals

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

### Embed Badge

![Health badge](/badges/corentinbtmps-laravel-vitals/health.svg)

```
[![Health](https://phpackages.com/badges/corentinbtmps-laravel-vitals/health.svg)](https://phpackages.com/packages/corentinbtmps-laravel-vitals)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[spatie/laravel-health

Monitor the health of a Laravel application

88011.3M149](/packages/spatie-laravel-health)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k51.0M7.4k](/packages/larastan-larastan)[craftcms/cms

Craft CMS

3.6k3.6M2.9k](/packages/craftcms-cms)[illuminate/queue

The Illuminate Queue package.

20432.2M1.5k](/packages/illuminate-queue)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
