Search by

lucasp1337 / laravel-loom

lucasp1337

Static architectural inspector for Laravel applications — emits a JSON index of events, listeners, and observers.

Package info

github.com/lucasp1337/laravel-loom

pkg:composer/lucasp1337/laravel-loom

Fund package maintenance!

lucasp1337

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 9

v0.2.0 2026-05-17 16:37 UTC

README

Laravel Loom — Architecture as data

Tests License

Laravel Loom

Loom is a static analyzer that maps a Laravel app's events, listeners, jobs, mailables, notifications, schedules and routes into a JSON index, a browser UI and an MCP server.

Laravel wires an event up in several places at once: dispatched in a controller, handled by a listener that was auto-discovered from a type hint, and observed by a closure in a provider. Loom reads your source and answers "what happens when OrderPlaced fires?" in one lookup, with a file and line for every hop.

composer require lucasp1337/laravel-loom --dev
php artisan loom:scan
php artisan loom:show OrderPlaced
{
  "events": [
    {
      "id": "App\\Events\\OrderPlaced",
      "file": "app/Events/OrderPlaced.php",
      "line": 5,
      "dispatched_from": [
        { "file": "app/Http/Controllers/OrderController.php", "line": 11, "method": "App\\Http\\Controllers\\OrderController::store" }
      ],
      "handled_by": [
        { "listener": "App\\Listeners\\SendOrderConfirmation", "method": "handle" }
      ]
    }
  ]
}

That is an excerpt: the scan wrote storage/loom/index.json, and loom:show printed it filtered to OrderPlaced. Open /loom in your local app to browse the same data. Getting started walks through it step by step.

What you can do with it

  • See the wiring. Every primitive, forward and backward, in one index. What gets picked up is in what Loom sees.
  • Browse it. A read-only UI at /loom: browse the UI.
  • Ask an agent. php artisan loom:mcp serves the index to an MCP client: ask an agent.
  • Gate your CI. loom:check fails pull requests that add dead events or dispatch cycles, and loom:diff shows how the architecture changed between branches: gate your CI.
  • Read it from code. Load the index into typed PHP objects: PHP API.

What it is not

  • Not a runtime tracer. Loom never boots your app or watches a request, so it reports what your source says, not what a given request did.
  • Not complete for dynamic code. A dispatch like event($class) can't be resolved from source. Loom lists it under unresolved_dispatches with a file and line instead of guessing.
  • Not a style linter. It has no opinion on your code beyond the check rules you turn on.

Note

Install with --dev. The UI, the MCP server and the viewLoom gate then disappear from composer install --no-dev production builds. The UI is also mounted only in local unless you list more environments in loom.ui.environments.

Requirements

  • PHP 8.3 or newer
  • Laravel 11, 12 or 13

livewire/livewire and laravel/mcp (^1.0) are required dependencies; Composer installs them with Loom (see upgrading).

Documentation

Start at getting started, or see the command reference and the JSON schema.

Contributing

See CONTRIBUTING.md.

License

The MIT License (MIT). See LICENSE.md.