Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ranger Laravel Package

laravel/ranger

Ranger is a Laravel introspection library that walks your codebase and collects routes, models, enums, broadcast events, environment variables, and Inertia components. Register callbacks that fire as each item is discovered and receive a detailed DTO. Currently in beta.

View on GitHub
Deep Wiki
Context7

Getting Started

Ranger is a read-only introspection layer: you resolve one Ranger instance, register callbacks for the components you care about, then call walk() once. Treat it as build-time tooling rather than request-time code.

composer require laravel/ranger

Because Ranger is still in beta, pin a known version in composer.json and watch the changelog before upgrading. The API is explicitly expected to change before v1.0.0.

Minimal first use case — dump every route URI and controller to understand an unfamiliar application:

use Illuminate\Support\Facades\Artisan;
use Laravel\Ranger\Components;
use Laravel\Ranger\Ranger;

Artisan::command('app:routes-inventory', function (Ranger $ranger) {
    $ranger->onRoute(function (Components\Route $route) {
        $this->line(sprintf(
            '%-6s %-40s %s',
            implode('|', $route->methods()),
            $route->uri(),
            $route->controller() ?? 'closure',
        ));
    });

    $ranger->walk();
});

Where to look first:

  • Laravel\Ranger\Ranger — the callback registration surface (onRoute, onModel, onEnum, onBroadcastEvent, plus the collection variants).
  • Laravel\Ranger\Components\* — the DTOs. These are the real API you'll build against; inspect their methods before designing output.
  • The README's "What Ranger Collects" table — routes, models, enums, broadcast events/channels, env vars, Inertia shared data and components.
  • Ignore markers, since they affect what your tooling will and won't see.

A good first production use is an internal contract report: route inventory, model/relationship map, enum values, Inertia page props, and env var names, emitted as JSON artifacts from CI.

Implementation Patterns

Register everything, walk once. Ranger scans the application; don't call walk() per collector. Build up callbacks, collect into local arrays or DTOs, then emit in the collection callbacks.

$ranger = app(Ranger::class);

$routes = [];
$ranger->onRoute(function (Components\Route $route) use (&$routes) {
    $routes[] = [
        'uri' => $route->uri(),
        'methods' => $route->methods(),
        'controller' => $route->controller(),
        'parameters' => $route->parameters(),
        'validation' => $route->validationRules(),
        'responses' => $route->responses(),
    ];
});

$ranger->onRoutes(function ($allRoutes) use (&$routes) {
    file_put_contents(
        storage_path('app/ranger/routes.json'),
        json_encode($routes, JSON_PRETTY_PRINT)
    );
});

$ranger->walk();

Generate frontend contracts from backend truth. The route, Inertia component, and enum collectors are the highest-leverage combination for Laravel + Inertia applications:

  • Routes → a TypeScript route helper or a typed URL map. Include validation rules and possible responses where the DTO exposes them, but treat inferred response shapes as hints rather than a replacement for hand-reviewed API docs.
  • Enums → TypeScript union types or const maps. Backed enums give you case values; unit enums are also handled.
  • Inertia components → expected prop names and optionality. Use this to catch a page component that's missing a prop the controller shares, or to generate prop interfaces.
  • Inertia shared data → audit what's globally injected into every page, especially when trimming payloads.

Use models for schema and relationship documentation. Model DTOs expose attributes, types, relationships, and file paths. This is useful for Mermaid ERDs, onboarding docs, and detecting relations that point at classes that no longer exist. Note that $hidden, $visible, and $appends are respected, so the output reflects serialization rather than raw database columns — which is usually what you want for API-facing docs.

Make it a diffable CI artifact. Run Ranger in a CI job, write deterministic JSON, commit or upload it, and diff against the previous run. That turns introspection into change detection: new routes without tests, removed enum cases, changed event payloads, or a dropped Inertia prop become reviewable. Sort collections before writing, because discovery order is not a contract.

Design intentional ignore markers before you need them. Ranger honors attributes implementing Laravel\Surveyor\Contracts\Ignored on models, enum cases, broadcast events/channels, and controller classes/actions. Use conditional markers for environment-specific or integration-specific declarations:

#[Ignore(unless: 'services.fake_source_provider')]
case GitFake = 'gitfake';

Conditions can be a config key, a [class, method] callable, or a bool. This lets the same cached analysis serve different environments while still excluding what should be excluded.

Integrate with existing tooling rather than replacing it. Keep Ranger output as an input to your OpenAPI generator, TypeScript generator, or documentation pipeline. It is an introspection source, not a runtime router or a substitute for feature tests.

Gotchas and Tips

  • Beta means pin and read the changelog. The package is at 0.x and the API is subject to change. Pin a version, upgrade deliberately, and keep your integration thin so a DTO rename is a small fix rather than a rewrite.
  • One scan, not many. Upgrading past v0.4.0 matters if you're on an older release — earlier versions rescanned the application for each collector. Even so, avoid calling walk() repeatedly in one process.
  • Don't run Ranger in HTTP requests. It walks the codebase and is naturally CLI/CI-shaped. Put it behind an Artisan command or a dedicated job, not a controller.
  • Conditions are resolved at collection time, not analysis time. This is intentional: a cached analysis can still answer correctly for the environment doing the collecting. If you change ignore conditions, re-run the collection step.
  • Ignoring a controller drops its routes. Ignoring a model also drops relationships pointing at it, because there's no type left to point at. That's correct for privacy/serialization, but it can make a generated graph look incomplete — document or test these exclusions.
  • Static inference has limits. Route binding types are resolved via the Surveyor analyzer, union types are handled in Inertia merging, and API resource/arrayable responses are collected, but inferred response shapes are still heuristics. Validate generated API contracts against actual tests or a real schema.
  • Domain, base path, and port handling has a history of fixes. If your application uses Route::domain(...), an APP_URL base path, or a non-standard port, verify generated URIs rather than assuming they match production URLs.
  • Serialization rules are respected. $hidden, $visible, and $appends affect model components. This prevents leaking hidden attributes, but it also means the introspection output may differ from getAttributes() on the class. Don't treat it as a raw schema dump.
  • Broadcast coverage includes ShouldBroadcastNow. If your event inventory seems complete but a specific event is missing, check whether it implements ShouldBroadcast, ShouldBroadcastNow, or neither — and whether a marker is excluding it.
  • Enum handling covers both backed and unit enums. Older releases had unit-enum bugs; if enum values look wrong, check the version before writing custom workarounds.
  • Use the collection callbacks for final output. Per-item callbacks fire as items are discovered; onRoutes, onModels, etc. fire after discovery. Ordering-sensitive output belongs there.
  • Debug incrementally. If a full report looks wrong, register only onRoutes or only onModels, dump() the DTO type and payload, then add collectors back. Most surprises are either an ignored declaration or an inference limitation, not a Ranger bug.
  • Assess maturity honestly. The package is Laravel-maintained but early: low star count and no dependents. That's fine for internal tooling that you can replace, less fine as a hard dependency in a critical deploy path. Keep the integration isolated behind one command or service class.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections
webx-ui/module-catalog-feeds
makidizajnerica/laravel-dto
matviib/scheduler
webx-ui/templates
anodyne/blade-tabler-icons
bref/laravel-websockets
anodyne/blade-hugeicons
1994/flatpack-statamic