Skip to main content
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.

Latest release status (April 2026)

PackageLatest releaseNotes
laravel/rosterv0.5.1laravel/boost’s composer.json requires ^0.5.0, and its BoostServiceProvider calls Roster::scan(base_path())
laravel/rangerv0.1.12Depends on laravel/surveyor:^0.1.0 in composer.json
laravel/surveyorv0.1.9The lower-layer analysis foundation used by ranger

Overview

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.
PackageRoleInstallation
laravel/surveyorStatic analysis engine for PHP codecomposer require laravel/surveyor
laravel/rangerIntrospection across the entire Laravel appcomposer require laravel/ranger
laravel/rosterEcosystem package detectioncomposer require laravel/roster --dev
Let’s look at each package in detail.

laravel/surveyor — the static analysis engine

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.

Installation

composer require laravel/surveyor

Basic usage

Analyze a file

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();

Analyze a class directly

$result = $analyzer->analyzeClass(\App\Models\User::class);
$classResult = $result->result();

Information available from ClassResult

$classResult = $analyzer->analyzeClass(App\Models\User::class)->result();

// Class info
$name = $classResult->name();            // 'App\Models\User'
$namespace = $classResult->namespace();  // 'App\Models'
$filePath = $classResult->filePath();

// Inheritance
$extends = $classResult->extends();
$implements = $classResult->implements();

// Method info
$method = $classResult->getMethod('store');
$returnType = $method->returnType();
$parameters = $method->parameters();
$rules = $method->validationRules(); // Validation rules are also available

// Property info
$property = $classResult->getProperty('email');
$type = $property->type;
$visibility = $property->visibility; // 'public', 'protected', 'private'

// Lists of public methods and properties
$publicMethods = $classResult->publicMethods();
$publicProperties = $classResult->publicProperties();

Type system

Surveyor has a rich type system that structures PHP types.
use Laravel\Surveyor\Types\Type;

// Creating various types
$stringType = Type::string();
$intType = Type::int();
$boolType = Type::bool();
$nullType = Type::null();

// Union type (e.g. string|null)
$unionType = Type::union(Type::string(), Type::null());

// Type checks
use Laravel\Surveyor\Types\StringType;

if (Type::is($returnType, StringType::class)) {
    // Handle string type
}

Cache configuration

You can cache analysis results to improve performance on repeated runs.
use Laravel\Surveyor\Analyzer\AnalyzedCache;

// Enable disk cache
AnalyzedCache::enableDiskCache(storage_path('surveyor-cache'));

// Clear the cache
AnalyzedCache::clear();
It can also be configured via environment variables.
SURVEYOR_CACHE_ENABLED=true
SURVEYOR_CACHE_DIR=/path/to/cache

Eloquent model analysis

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 — high-level introspection

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.

Installation

composer require laravel/ranger

Basic usage

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();

Components Ranger collects

CollectorDescription
RoutesAll registered routes (URI, parameters, HTTP methods, controller, validation rules, responses)
ModelsEloquent models with attributes, types, and relationships
EnumsPHP Backed Enums (with integer or string values) and their cases and values
BroadcastEventsEvents implementing ShouldBroadcast with their payloads
BroadcastChannelsRegistered broadcast channels
EnvironmentVariablesEnvironment variables defined in .env
Inertia Shared DataGlobally shared Inertia.js props
Inertia ComponentsInertia.js page components and their expected props

laravel/roster — a package detection tool

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?”

Installation

composer require laravel/roster --dev

Basic usage

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.

Real-world use cases

AI guideline generation tool (Boost)

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.

Building a package compatibility checker

If you’re developing a package that behaves differently depending on which packages are installed in the user’s project, roster is very useful.
use Laravel\Roster\Roster;
use Laravel\Roster\Packages;

$roster = Roster::scan(base_path());

if ($roster->uses(Packages::INERTIA)) {
    // Inertia-specific behavior
    if ($roster->usesVersion(Packages::INERTIA, '2.0.0', '>=')) {
        // Inertia v2+ behavior
    }
}

if ($roster->uses(Packages::LIVEWIRE)) {
    // Livewire-specific behavior
}

// Choose install commands based on the JavaScript package manager
$pm = $roster->nodePackageManager();
echo "Run: {$pm} install your-package";

Automatic application documentation generation

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

Summary

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.

laravel/surveyor

Static analysis engine for PHP code

laravel/ranger

High-level introspection library

laravel/roster

Package detection tool
Last modified on July 13, 2026