lychee-org/phpstan-lychee
PHPStan extension for Lychee that adds custom rules, stubs, and type information to improve static analysis of Lychee-based Laravel applications. It helps catch Lychee-specific errors earlier, enforce coding standards, and keep analysis consistent across projects.
Architecture fit. lychee-org/phpstan-lychee is a static-analysis ruleset, not a runtime library. It occupies the tooling layer of a Laravel/PHP stack — a Composer require-dev dependency consumed by PHPStan, typically only inside CI and pre-commit hooks. It never ships to production, has no runtime surface, no database or queue interaction, and no framework coupling beyond PHPStan's own rule API. That makes it architecturally "free" to trial and equally free to discard, which is the main reason it is worth a look at all.
Integration feasibility. Mechanically trivial: add the package to require-dev, confirm it registers via phpstan/extension-installer or an explicit includes: entry in phpstan.neon, run the analyser. The real question is not whether it installs but whether its rules are domain-bound or convention-generic. Lychee is a self-hosted Laravel photo manager; a ruleset maintained "for all Lychee related php repo" is most likely a mix of generic hygiene rules (strict types, forbidden debug helpers, facade usage discipline) and rules that reference Lychee-specific classes, namespaces, or architectural boundaries. The former are portable; the latter are inert at best and hard-error at worst when pointed at a codebase that does not contain the referenced symbols.
Technical risk. High relative to the value on offer:
composer.json constraints.Key questions to answer before spending more than a day on this.
composer.json require for phpstan/phpstan and php, and how wide is that constraint?src/ namespace?phpstan/extension-installer entry, or does it require manual includes: and rule registration?Stack fit. Good on paper for any Laravel 10/11/12 codebase already running PHPStan in CI. Zero coupling to application runtime, service container, or deployment topology. The package's only real dependency is the analyser itself, so it slots into the existing quality gate alongside Pint, PHP-CS-Fixer, and PHPUnit rather than displacing anything.
Migration path. There is no migration — adoption is additive and reversible in a single commit. The recommended path is a spike, then fork, then own:
composer require --dev lychee-org/phpstan-lychee, run vendor/bin/phpstan analyse with your existing config plus the package's include. Capture the delta in findings versus a clean baseline. Record any hard failures caused by unresolvable symbols.phpstan-rules package (or a tools/phpstan/ directory) and re-target their namespace references at your own domain. This converts a 1-star external dependency into an owned asset with a known maintainer — you.rules: in phpstan.neon rather than pulling the whole extension, so each rule is individually attributable and individually removable.Compatibility. Pin PHPStan in lockstep with whatever the package supports. If the package pins an older PHPStan major, do not let it hold back your analyser upgrade — fork the rules and port them instead. Check PHP version constraints against your CI matrix; a Laravel 12 codebase on PHP 8.3+ may sit outside the package's tested range.
Sequencing. Run the spike behind a feature branch with reportUnmatchedIgnoredErrors: false and a baseline file so the team sees incremental signal rather than a wall of pre-existing violations. Land high-confidence rules first (strict types, forbidden dd/dump, disallowed env() outside config). Defer architectural-boundary rules — those encode someone else's design opinions about Lychee and rarely transfer without translation.
Maintenance. The honest answer is that if you depend on this package, you own it. At 0 dependents and 1 star there is no upstream community absorbing maintenance, no security advisory pipeline, and no expectation that a PHPStan major release will be tracked promptly. Budget the fork explicitly in the initial estimate; treating the fork as the deliverable rather than an escape hatch avoids the common failure where a team adopts the dependency, hits a breaking PHPStan upgrade eight months later, and disables the whole ruleset rather than porting it.
Support. Effectively community-of-one. Escalation is a GitHub issue on a repository whose maintainer's primary obligation is the Lychee product, not this package. Do not place this on a critical path where a stalled issue blocks a release. Static analysis should always be advisory or independently revertable for exactly this reason.
Scaling. Analysis cost scales with codebase size, not with this package — the added rules are a marginal increment. Run PHPStan with --memory-limit tuned and use the result cache (tmpDir) in CI. For monorepos, shard analysis per-package. The scaling risk is organisational, not computational: every false positive costs developer trust, and trust in a static analysis gate is expensive to rebuild once lost. Enforce a rule only after it has been clean on the default branch for a sprint.
Failure modes to design against.
ignoreErrors entries that quietly disable rules you actually wanted — mitigated by per-rule enablement and reviewing the ignore file each quarter.Ramp-up. Low for the team consuming findings: engineers read PHPStan output already. Moderate for whoever owns the fork — writing or porting a rule requires comfort with PHPStan's Rule interface, NodeType dispatch, and Scope reflection, which is a niche skill. Realistically one engineer for two to four days to fork, re-target, and wire into CI, then a few hours per PHPStan major to keep current. That cost is small and bounded, which is precisely why the fork-and-own path is preferable to a dependency on a package with no other consumers.
TPM verdict. Leverage here is as a seed corpus and reference implementation, not as an adopted dependency. Value: low-to-moderate and entirely contingent on the rules being portable. Effort: small and bounded. Risk of direct adoption: disproportionate. Recommend a two-day spike with fork-and-own as the expected outcome, and no production path dependency under any scenario.
How can I help you explore Laravel packages today?