lucasp1337 / laravel-loom
Static architectural inspector for Laravel applications — emits a JSON index of events, listeners, and observers.
Fund package maintenance!
Requires
- php: ^8.3
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- justinrainbow/json-schema: ^6.0
- nikic/php-parser: ^5.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- phpstan/extension-installer: ^1.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-19 19:44:25 UTC
README
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:mcpserves the index to an MCP client: ask an agent. - Gate your CI.
loom:checkfails pull requests that add dead events or dispatch cycles, andloom:diffshows 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 underunresolved_dispatcheswith 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.