Skip to content

Laravel ​

A complete, copy-paste walkthrough: start a new Laravel app, snapshot its welcome page with Dungbeetle, introduce a change, and read the semantic diff. It uses the default web capture with the zero-dependency fetch driver — no browser install required.

Prerequisites ​

  • PHP 8.2+ and Composer — to create and serve the Laravel app.
  • Node.js 22 or newer — Dungbeetle's runtime (node --version to check).

1. Create a new Laravel app ​

Scaffold a fresh project with Composer and move into it:

sh
composer create-project laravel/laravel example-app
cd example-app

That gives you Laravel's default welcome page, served at http://127.0.0.1:8000 by php artisan serve.

The default Laravel welcome page in a browser at http://127.0.0.1:8000.

2. Install Dungbeetle ​

Add Dungbeetle as a dev dependency so the version is pinned per project:

sh
npm install --save-dev dungbeetle
npx dungbeetle --version

3. Scaffold a config ​

Generate a starter dungbeetle.config.json:

sh
npx dungbeetle init

init detects the Laravel app via composer.json and scaffolds check targets for it automatically — routes, about, schedule, schema, plus tests/style/static-analysis for whichever tools are installed. Those work as-is (step 9 puts them through their paces). For this walkthrough's welcome-page snapshot, replace the config with the one below. It tells Dungbeetle to start the Laravel dev server, wait until it responds, and snapshot the welcome page — then shut the server down afterward:

json
{
  "version": 1,
  "project": { "name": "example-app" },
  "baselinesDir": "dungbeetle.snapshots",
  "artifactsDir": ".dungbeetle/artifacts",
  "lifecycle": {
    "start": ["php artisan serve"],
    "wait": { "url": "http://127.0.0.1:8000", "timeoutMs": 30000 },
    "capture": [
      { "kind": "web", "name": "welcome", "url": "http://127.0.0.1:8000" }
    ]
  }
}

Everything here is a default-friendly choice: baselines land in dungbeetle.snapshots/, artifacts in .dungbeetle/artifacts/, and the web target uses the default fetch driver (no Playwright, no browser). See Web snapshots and the full configuration reference for every option.

4. Validate the setup ​

Catch config and readiness problems before capturing anything:

sh
npx dungbeetle doctor

5. Capture the first baseline ​

sh
npx dungbeetle update

Dungbeetle boots php artisan serve, waits for http://127.0.0.1:8000, captures a structured DOM snapshot of the welcome page, writes it under dungbeetle.snapshots/, and stops the server. Commit the baseline — it's the reviewable record of your app's output:

sh
git add dungbeetle.snapshots
git commit -m "Add Dungbeetle baseline for welcome page"

6. Make a change and compare ​

Edit the welcome view so the output differs — for example, change the heading in resources/views/welcome.blade.php:

blade
<h1>Welcome to Example App</h1>

Now compare current output against the baseline:

sh
npx dungbeetle test

test boots the server again, re-captures, and exits non-zero because the DOM changed. The diff is semantic — a node-level text-changed, not a pixel blob.

7. Read the report ​

Generate an HTML report and open it:

sh
npx dungbeetle ci --json report.json --html report.html
open report.html   # macOS; use xdg-open on Linux

Screencast: doctor → the edited Blade view fails test with a semantic diff → update accepts it → test passes.

Flow video — the terminal session replayed, then the served page with its change, then the failing run's HTML report.

8. Accept the new baseline ​

Once the change is intended, promote it to the new baseline and commit:

sh
npx dungbeetle update
git add dungbeetle.snapshots && git commit -m "Update welcome baseline"

9. Snapshot the app's shape ​

The scaffolded check targets from step 3 snapshot what the app is, not just what it renders — every route with its middleware, the scheduled jobs, the database schema, the test suite's results, and style/static analysis when Pint or Larastan are installed. Each is one line of config:

json
{ "kind": "check", "name": "routes", "tool": "laravel-routes" }

Baseline them all at once:

sh
npx dungbeetle update && git add dungbeetle.snapshots && git commit -m "Baseline app shape"

Now make a risky change — remove a route, or run a migration that drops a column — and npx dungbeetle test names it precisely:

diff
~ $.data.GET|HEAD /orders: {"middleware":["web","auth"],…} → undefined
~ $.data.users.nickname: "varchar" → undefined

A route that lost its auth middleware, a dropped column, a newly failing test — each is one named line in the diff, not a wall of tool output.

Screencast: init detects the Laravel app and scaffolds the check targets → baseline → a renamed route fails test with the route and the Feature test that hits it, both named.

10. Review in the cloud ​

Push a run to a Dungbeetle server to review and approve these diffs in a browser — without committing baselines to the repo:

sh
npx dungbeetle ci --json .dungbeetle/ci-report.json --with-snapshots --json-only
DUNGBEETLE_CLIENT_ID=cid_… DUNGBEETLE_CLIENT_SECRET=csec_… \
  npx dungbeetle push --report .dungbeetle/ci-report.json --branch main

Pushes go to the hosted cloud by default. Self-hosting? Point the CLI at your server with --server <url> or DUNGBEETLE_SERVER_URL.

The review UI renders each check target as a risk-first table — the removed route, the dropped column, and the newly failing test sort to the top with summary chips on the clean targets:

Screencast: sign in → open the failing run → read the risk-first check tables → approve and promote the new baselines.

See Push runs and baselines for the API details.

Next steps ​

  • Add more targets — extra routes, JSON API responses, or an Artisan command via a terminal capture.
  • Need browser-rendered DOM, accessibility, or screenshots? Switch the target to the Playwright driver.
  • Wire npx dungbeetle ci into CI, or push runs to the cloud server to review diffs in a browser without committing baselines.

Source-available: CLI under FSL-1.1-ALv2, cloud server under BUSL-1.1. See Licensing.