An introduction to the three packages that make up Laravel’s newly published static analysis ecosystem: surveyor, ranger, and roster. A guide to the new tools that package developers and tool authors should know about—from PHP code analysis to package detection.
This article is based on the GitHub repository READMEs and source code. All three packages are still in Beta ahead of a formal release (as of April 2026).
surveyor, ranger, and roster are all in Beta. APIs may change before v1.0.0 is released. Use in production with caution.
Entering 2026, Laravel has published three packages related to code analysis. Each can be used on its own, but together they form a code analysis ecosystem.
laravel/surveyor is a static analysis tool that parses PHP files and provides detailed metadata about classes, methods, properties, return types, and more in a structured form. It’s specialized in extracting information in a form other tools and packages can consume.
use Laravel\Surveyor\Analyzer\Analyzer;$analyzer = app(Analyzer::class);// Analyze by file path$result = $analyzer->analyze('/path/to/your/File.php');// Access the analyzed scope$scope = $result->analyzed();// Access the class result$classResult = $result->result();
You can cache analysis results to improve performance on repeated runs.
use Laravel\Surveyor\Analyzer\AnalyzedCache;// Enable disk cacheAnalyzedCache::enableDiskCache(storage_path('surveyor-cache'));// Clear the cacheAnalyzedCache::clear();
It can also be configured via environment variables.
Surveyor treats Eloquent models specially by trying to connect to the database. Model relationships, attributes, accessors, and casts are also detected.
$result = $analyzer->analyzeClass(App\Models\User::class)->result();// Database attributes are auto-detected$emailProperty = $result->getProperty('email');// Identify relationship methods$method = $result->getMethod('posts');if ($method->isModelRelation()) { // This method is a relationship}
Because Surveyor attempts to connect to the database when analyzing Eloquent models, it’s not purely static analysis. Performance and memory usage are also under active improvement, and contributions are welcome.
laravel/ranger wraps surveyor to provide a high-level library that walks through your entire Laravel application and collects information on routes, models, enums, broadcast events, environment variables, Inertia components, and more.
Use callbacks to describe what should happen when each component is discovered.
use Laravel\Ranger\Ranger;use Laravel\Ranger\Components;use Illuminate\Support\Collection;$ranger = app(Ranger::class);// Called every time a route is discovered$ranger->onRoute(function (Components\Route $route) { echo $route->uri();});// Called every time a model is discovered$ranger->onModel(function (Components\Model $model) { foreach ($model->getAttributes() as $name => $type) { // Handle attribute name and type }});// Called every time an enum is discovered$ranger->onEnum(function (Components\Enum $enum) { //});// Called every time a broadcast event is discovered$ranger->onBroadcastEvent(function (Components\BroadcastEvent $event) { //});// Called once after all routes are collected$ranger->onRoutes(function (Collection $routes) { //});// Called once after all models are collected$ranger->onModels(function (Collection $models) { //});// Walk the entire application and fire callbacks$ranger->walk();
laravel/roster is a tool that detects which Laravel ecosystem packages are installed in a project. Package developers and tool authors can easily answer questions like “does this project use Inertia?” and “which Livewire version is installed?”
use Laravel\Roster\Roster;use Laravel\Roster\Packages;// Scan a directory and obtain a Roster instance$roster = Roster::scan($directory);// List installed packages$roster->packages();// Production packages only$roster->packages()->production();// Dev-only packages$roster->packages()->dev();// Check for a specific package$roster->uses(Packages::INERTIA); // bool$roster->uses(Packages::LIVEWIRE); // bool// Check with a version constraint$roster->usesVersion(Packages::INERTIA, '2.0.0', '>='); // Inertia 2.0.0+?$roster->usesVersion(Packages::LIVEWIRE, '3.0.0', '>='); // Livewire 3.0.0+?// Detect the JavaScript package manager$packageManager = $roster->nodePackageManager(); // 'npm', 'yarn', 'bun', etc.
Laravel Boost uses roster to understand the installed package layout and automatically tune the guidelines and skills it generates for AI agents (like GitHub Copilot and Claude). Based on facts such as “does this project use Inertia?” and “is Livewire installed?”, it selects the appropriate guideline files and supplies them to the AI agent.
With ranger, you can build a tool that automatically collects routes, models, and enums from a Laravel app and generates documentation.
use Laravel\Ranger\Ranger;use Laravel\Ranger\Components;$ranger = app(Ranger::class);$docs = [];$ranger->onRoute(function (Components\Route $route) use (&$docs) { $docs['routes'][] = [ 'uri' => $route->uri(), // Route validation rules and response types are also available ];});$ranger->onModel(function (Components\Model $model) use (&$docs) { $docs['models'][] = [ 'attributes' => $model->getAttributes(), ];});$ranger->walk();// $docs now contains structural information for the entire app
surveyor, ranger, and roster provide a new foundation for programmatic code analysis in the Laravel ecosystem.These packages are aimed primarily at package developers and tool authors—they aren’t intended for direct use by end users. Even so, they’re actively used inside official Laravel tools like Laravel Boost, and ecosystem adoption is expected to grow.