Eric L. Barnes introduced Laravel Vet on September 15, 2026. The beta package from the Laravel team previews files that an install or update would place in vendor/ and stores approved package states in vet.json. It runs after installs and blocks an update before new files are written. Its workflow follows cargo vet from Rust. Packages that have already been approved stay quiet, while changed packages return for review.

terminal
composer require laravel/vet --dev
./vendor/bin/vet --init
composer update
./vendor/bin/vet

Vet can send each package diff to a coding agent installed on the local machine, including Claude Code, Codex, Gemini, and opencode. The agent reports PASS, FAIL, WARN, or SKIP. PASS means the review completed without an attack being reported. FAIL names a file and explains the problem. WARN marks an incomplete review, such as a file that is too large, contains non-text data, or received no answer. SKIP means Vet sent no files because nothing changed or the package files could not be read. An untrusted package produces a non-zero exit status, which can stop a build. The tool works with any project containing composer.json, including Laravel, Symfony, WordPress, and plain PHP.

Vet requires PHP 8.4 or later and is installed as a development dependency. The initial setup trusts the packages already present in vendor/ and writes them to vet.json. In the documented run, the file recorded 125 packages. This step records the files on disk without reviewing them. Future updates are checked against that baseline.

A sample composer update found carbonphp/carbon-doctrine-types moving from 3.1.0 to 3.2.0 with two changed files. The update changed a return type in src/Carbon/Doctrine/DateTimeImmutableType.php from DateTimeImmutable to CarbonImmutable. It changed the corresponding type in src/Carbon/Doctrine/DateTimeType.php from DateTime to Carbon. Vet stopped before writing the new files and offered detailed review with ./vendor/bin/vet -v or agent-assisted review with ./vendor/bin/vet.

In one agent-assisted run, Claude reviewed three packages totaling 58.1 KB. The update for acme/logger from 1.2.0 to 2.0.0 changed 12 files. The agent returned FAIL because src/Ship.php read .env and posted its contents to telemetry.example.com. The acme/tooling update from 4.1.0 to 4.2.0 changed eight files. It received WARN because the changes added two commands and resources/schema.php was a 612.4 KB file that the agent did not read. The carbonphp/carbon-doctrine-types update received PASS after the agent reviewed two files and found narrower return types.

Vet selects PASS packages by default. Developers can change the selection after reading the reports and press Enter to record their choices. Agent results alone do not modify vet.json. Vet stores the file next to composer.json, and the article recommends committing it to the repository. An entry uses schema version 4 and records a package version plus a hash. The example contains version 3.2.1 and the hash tree-v2:0f158f3b909fc01e691ed5f5121186056232b049031e7d3a914676d49881ece5. The hash covers every package file, so a file change requires another review even when the version number stays the same. A build fails until every package is trusted.

The guide places Vet in the context of recent supply-chain incidents. It mentions Composer 2.10’s malware blocking and dependency policies, along with an Axios npm package that shipped a remote access trojan. Vet remains in beta, so its behavior may change before a stable release. The article also points to Heimdall, which applies a minimum-age policy to Composer dependencies, and to the laravel/vet GitHub repository for documentation.