PHPackages                             laravel/roster - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. laravel/roster

ActiveLibrary[Framework](/categories/framework)

laravel/roster
==============

Detect packages &amp; approaches in use within a Laravel project

v1.0.0(1mo ago)16225.5M—0%18[2 issues](https://github.com/laravel/roster/issues)6MITPHPPHP ^8.2CI passing

Since Jul 21Pushed 3w ago1 watchersCompare

[ Source](https://github.com/laravel/roster)[ Packagist](https://packagist.org/packages/laravel/roster)[ Docs](https://github.com/laravel/roster)[ RSS](/packages/laravel-roster/feed)WikiDiscussions 1.x Synced 2w ago

READMEChangelog (10)Dependencies (31)Versions (31)Used By (6)

Laravel Roster
==============

[](#laravel-roster)

[![Build Status](https://github.com/laravel/roster/workflows/tests/badge.svg)](https://github.com/laravel/roster/actions)[![Total Downloads](https://camo.githubusercontent.com/6f3f71ab4253089feba05670289fcff1d846f199146d312b4cc5262a3c906c64/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c61726176656c2f726f73746572)](https://packagist.org/packages/laravel/roster)[![Latest Stable Version](https://camo.githubusercontent.com/d83b9c29743dfb7b500c887df886b513e81b98466b28f88c84c1a629e516bed1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c61726176656c2f726f73746572)](https://packagist.org/packages/laravel/roster)[![License](https://camo.githubusercontent.com/fcde7a997fbd11b0ae3ed21bfdeb9c5b4ea0a28d0a74587065378336e2c0ab4e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c61726176656c2f726f73746572)](https://packagist.org/packages/laravel/roster)

- [Introduction](#introduction)
- [Installation](#installation)
- [Basic Usage](#basic-usage)
- [Detecting Packages](#detecting-packages)
    - [Minimum PHP Version](#minimum-php-version)
    - [Version Constraints](#version-constraints)
    - [Checking Multiple Packages](#checking-multiple-packages)
    - [Retrieving Packages](#retrieving-packages)
- [Detecting Stacks and Frontends](#detecting-stacks-and-frontends)
- [Detecting Agents and Editors](#detecting-agents-and-editors)
- [Detecting JS Package Managers](#detecting-js-package-managers)
- [Detecting Approaches](#detecting-approaches)
- [Caching](#caching)
- [The `roster:scan` Command](#the-rosterscan-command)
- [Upgrading](#upgrading)
- [Contributing](#contributing)
- [Code of Conduct](#code-of-conduct)
- [Security Vulnerabilities](#security-vulnerabilities)
- [License](#license)

Introduction
------------

[](#introduction)

Laravel Roster is a detection package for the Laravel ecosystem. It reads your project's lockfiles and configuration markers and can optionally inspect source code to determine what the project uses.

The `Project` facade reports package dependencies, the application's stack and frontend, browser test frameworks, configured AI agents and editors, the JS package manager indicated by the committed lockfile, and conventions adopted by the codebase.

Installation
------------

[](#installation)

You may install Roster as a development dependency via the Composer package manager:

```
composer require laravel/roster --dev
```

Basic Usage
-----------

[](#basic-usage)

Within a Laravel application, you may call the `Project` facade directly. The first call triggers a scan, and the result is reused by subsequent facade calls:

```
use Laravel\Roster\Enums\Stack;
use Laravel\Roster\Facades\Project;

Project::php()->uses('pestphp/pest');
Project::stacks()->uses(Stack::InertiaReact);
```

Outside a Laravel service container, or when you want an explicit project instance, instantiate the manager directly. It runs without caching when no container or cache driver is available:

```
use Laravel\Roster\ProjectManager;

$projects = new ProjectManager;

$project = $projects->scan(); // Uses base_path() or getcwd().
$project = $projects->scan($basePath);
```

The following examples use `$project` for clarity, but the same calls are available through the facade.

Detecting Packages
------------------

[](#detecting-packages)

Packages are exposed through two ecosystems: `php()` for Composer packages and `js()` for JavaScript packages managed by npm, pnpm, Yarn, or Bun. Both ecosystems provide the same methods:

```
$ecosystem->uses(string|array $packages, ?string $constraint = null): bool
$ecosystem->usesAll(array $packages): bool
```

The `uses` method returns `true` when **any** of the given packages is present, while the `usesAll` method returns `true` only when **every** package is present. Use the package names that appear in `composer.json` or `package.json`:

```
$project->php()->uses('pestphp/pest');
$project->js()->uses('@inertiajs/react');
```

### Minimum PHP Version

[](#minimum-php-version)

The PHP ecosystem reports the minimum major and minor version allowed by the root `composer.json` requirement. When the requirement is missing or has no usable lower bound, Roster falls back to the running PHP version:

```
$project->minimumPhpVersion(); // "8.3"
```

### Version Constraints

[](#version-constraints)

You may pass a version constraint as the second argument to the `uses` method. It accepts any Composer Semver constraint, such as `^1.2.3`, `~1.2`, `>=11 =11 js()->packageManager() === JsPackageManager::Pnpm;
```

You may also check for a specific package manager via the `usesPackageManager` method, which accepts an enum case or its string value:

```
$project->js()->usesPackageManager(JsPackageManager::Pnpm);
$project->js()->usesPackageManager('pnpm');
```

Projects should commit only one supported JavaScript lockfile. If multiple lockfiles are present, Roster selects the first match in this order: npm, pnpm, Yarn, then Bun.

Detecting Approaches
--------------------

[](#detecting-approaches)

The `approaches` method inspects the project's **own source code**, not its manifests, and reports which stylistic conventions the application has adopted:

- `fillable` vs `guarded` mass assignment (including the `protected $fillable` property and `#[Fillable]` attribute)
- enum case capitalization (`SCREAMING_SNAKE_CASE`, `PascalCase`, or `camelCase`)
- pipe vs array validation-rule syntax
- inline validation vs form requests (`$request->validate([...])` vs dedicated `rules()` classes under `Http/Requests`)
- command configuration via the `#[AsCommand]` attribute vs the `$signature` or `$description` property
- notifications sent via `$notifiable->notify()` vs the `Notification` facade
- authorization via gates, `$user->can()`, or `$this->authorize()`
- authenticated user retrieval via the `Auth` facade, `$request->user()`, or the `auth()` helper
- model key style: UUID (`HasUuids`), ULID (`HasUlids`), or the default auto-incrementing key

You may check for one or more approaches or retrieve all detected results:

```
use Laravel\Roster\Enums\Approach;

$project->approaches()->uses(Approach::MassAssignmentFillable);
$project->approaches()->uses([
    Approach::ValidationPipeSyntax,
    Approach::ValidationArraySyntax,
]);
$project->approaches()->all(); // Collection
```

Detection is best-effort: Roster uses lightweight pattern matching rather than a full parser, so an unusual file may abstain or be classified based on a comment or string literal. Approaches are therefore reported with a confidence ratio rather than as exact answers.

A stylistic approach is reported only when it receives at least three votes and at least 80% of the votes cast. Each file casts at most one vote, except that enum capitalization receives one vote per enum case. Consequently, a 2/3 majority is rejected, a 4/5 majority passes, and an evenly split codebase produces no result. A file that mixes styles votes for its majority style and abstains when tied.

Each `ApproachResult` exposes the winning `approach`, its raw `confidence` ratio, the `matched` and `total` vote counts, and the `paths` of the files that voted. You may retrieve a result via the `result` method:

```
$result = $project->approaches()->result(Approach::MassAssignmentFillable);

$result->confidence; // 0.9
$result->matched;    // 9
$result->total;      // 10
$result->paths;      // ['/app/Models/User.php', ...]
```

Roster discovers source files by combining the PSR-4 autoload roots in `composer.json` with `app/`. It matches subdirectories such as `Models/` anywhere beneath those roots, so it also scans modular layouts such as `src/Domain/Orders/Models/`. The `vendor/` and `node_modules/` directories, as well as hidden directories, are always excluded.

Because source files can change without affecting a lockfile, approaches are never persisted with a cached scan. They are computed lazily once per scan instance and only when requested. The `toArray()` and `json()` methods omit them, while the `roster:scan` command accepts an `--approaches` flag to include them in its output.

Caching
-------

[](#caching)

The first call through the `Project` facade scans the default project and memoizes the result for the remainder of the process. Across processes, Roster uses your application's configured cache driver. The cache key includes a hash of supported manifests and lockfiles, along with the presence of detector marker paths, so changes such as an edit to `composer.lock` or the addition of a `.claude` directory invalidate the persisted cache. Roster falls back to a direct scan when no cache driver is configured or the driver fails.

In long-running processes such as Octane or queue workers, the memoized instance is kept until the worker restarts. You may call `Project::fresh()` to bypass both the memoized result and the persisted cache and force a new scan at any time.

The `roster:scan` Command
-------------------------

[](#the-rosterscan-command)

The `roster:scan` Artisan command scans a directory and emits the project surface as a JSON document. When the directory is omitted, the application's base path is scanned:

```
php artisan roster:scan
php artisan roster:scan /path/to/project
```

You may pass `--approaches` to include approach detection for PHP files under the project's PSR-4 autoload roots and `app/` directory:

```
php artisan roster:scan /path/to/project --approaches
```

Upgrading
---------

[](#upgrading)

Please consult the [upgrade guide](UPGRADE.md) when upgrading from 0.x.

Contributing
------------

[](#contributing)

Thank you for considering contributing to Roster! You can find the contribution guide in the [Laravel documentation](https://laravel.com/docs/contributions).

Code of Conduct
---------------

[](#code-of-conduct)

To help ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](https://github.com/laravel/roster/security/policy) for instructions on reporting security vulnerabilities.

License
-------

[](#license)

Laravel Roster is open-source software licensed under the [MIT license](LICENSE.md).

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance94

Actively maintained with recent releases

Popularity67

Solid adoption and visibility

Community32

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~20 days

Recently: every ~39 days

Total

19

Last Release

26d ago

Major Versions

0.x-dev → v1.0.02026-07-18

PHP version history (2 changes)v0.1.0PHP ^8.2

v0.2.0PHP ^8.1|^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/463230?v=4)[Taylor Otwell](/maintainers/taylorotwell)[@taylorotwell](https://github.com/taylorotwell)

---

Top Contributors

[![ashleyhindle](https://avatars.githubusercontent.com/u/454975?v=4)](https://github.com/ashleyhindle "ashleyhindle (63 commits)")[![pushpak1300](https://avatars.githubusercontent.com/u/31663512?v=4)](https://github.com/pushpak1300 "pushpak1300 (24 commits)")[![HichemTab-tech](https://avatars.githubusercontent.com/u/84734617?v=4)](https://github.com/HichemTab-tech "HichemTab-tech (16 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![jjoek](https://avatars.githubusercontent.com/u/35167093?v=4)](https://github.com/jjoek "jjoek (5 commits)")[![taylorotwell](https://avatars.githubusercontent.com/u/463230?v=4)](https://github.com/taylorotwell "taylorotwell (3 commits)")[![nunomaduro](https://avatars.githubusercontent.com/u/5457236?v=4)](https://github.com/nunomaduro "nunomaduro (3 commits)")[![joetannenbaum](https://avatars.githubusercontent.com/u/2702148?v=4)](https://github.com/joetannenbaum "joetannenbaum (3 commits)")[![srinathreddydudi](https://avatars.githubusercontent.com/u/10626045?v=4)](https://github.com/srinathreddydudi "srinathreddydudi (1 commits)")[![webard](https://avatars.githubusercontent.com/u/855788?v=4)](https://github.com/webard "webard (1 commits)")[![ylynfatt](https://avatars.githubusercontent.com/u/19831?v=4)](https://github.com/ylynfatt "ylynfatt (1 commits)")[![AmadulHaque](https://avatars.githubusercontent.com/u/92516695?v=4)](https://github.com/AmadulHaque "AmadulHaque (1 commits)")[![zcuric](https://avatars.githubusercontent.com/u/1560102?v=4)](https://github.com/zcuric "zcuric (1 commits)")[![chris-ware](https://avatars.githubusercontent.com/u/19684457?v=4)](https://github.com/chris-ware "chris-ware (1 commits)")[![drewmt](https://avatars.githubusercontent.com/u/73502748?v=4)](https://github.com/drewmt "drewmt (1 commits)")[![duncanmcclean](https://avatars.githubusercontent.com/u/19637309?v=4)](https://github.com/duncanmcclean "duncanmcclean (1 commits)")[![jackbayliss](https://avatars.githubusercontent.com/u/13621738?v=4)](https://github.com/jackbayliss "jackbayliss (1 commits)")[![laserhybiz](https://avatars.githubusercontent.com/u/100562257?v=4)](https://github.com/laserhybiz "laserhybiz (1 commits)")[![mathieutu](https://avatars.githubusercontent.com/u/11351322?v=4)](https://github.com/mathieutu "mathieutu (1 commits)")[![soleinjast](https://avatars.githubusercontent.com/u/117115652?v=4)](https://github.com/soleinjast "soleinjast (1 commits)")

---

Tags

devlaravellaraveldev

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/laravel-roster/health.svg)

```
[![Health](https://phpackages.com/badges/laravel-roster/health.svg)](https://phpackages.com/packages/laravel-roster)
```

###  Alternatives

[laravel/sail

Docker files for running a basic Laravel application.

1.9k212.4M1.5k](/packages/laravel-sail)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

79227.1M228](/packages/laravel-mcp)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.6k26.0M808](/packages/laravel-boost)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k31.8M161](/packages/laravel-cashier)[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M322](/packages/laravel-ai)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
