Weave Code
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

Psalm Plugin Laravel Package

php-standard-library/psalm-plugin

Psalm plugin for PHP Standard Library (PSL) that improves type inference, especially for Psl\Type schemas (e.g., shape/optional), producing precise array shape types after coercion. Install via Composer and enable with psalm-plugin.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strong alignment with Laravel’s validation layer: The plugin bridges PSL’s expressive types (e.g., shape(), nullish(), non-empty-array) with Psalm’s static analysis, enabling zero-cost validation at compile time. This directly supports Laravel’s shift from runtime validation (e.g., Validator, FormRequest) to static contracts, reducing boilerplate and runtime overhead.
  • Complementary to Laravel’s type system: While Laravel lacks native support for PSL’s advanced types, this plugin enables precise type inference for PSL constructs, making it ideal for projects adopting PHP 8.2+ features (e.g., array{...} syntax) or modernizing legacy codebases.
  • Domain-driven design (DDD) enablement: PSL shapes can define immutable domain models (e.g., User, Order), with Psalm enforcing type safety across services, repositories, and API boundaries. This aligns with Laravel’s Eloquent but with stricter static guarantees.

Integration Feasibility

  • Low-friction adoption: The plugin integrates via Composer and a one-line CLI command (psalm-plugin enable), requiring minimal configuration. Existing Psalm setups (v4/v5) are supported, with backward compatibility for PSL v1/v2.
  • Gradual migration path: Can be introduced incrementally by:
    1. Annotating PSL shapes in domain models (e.g., Psl\Type\shape() for User).
    2. Enabling the plugin for targeted modules (e.g., API handlers).
    3. Expanding to full static validation as confidence grows.
  • Toolchain synergy: Works seamlessly with Laravel’s existing tooling (e.g., PestPHP, Laravel Pint) and IDEs (PHPStorm, VSCode) for real-time type feedback.

Technical Risk

  • Psalm version compatibility: Must align with Laravel’s Psalm adoption (e.g., if using Psalm v5, ensure plugin version ^2.1 is used). Risk mitigated by the plugin’s explicit compatibility matrix.
  • Performance overhead: Psalm analysis adds CPU/memory usage during development. Mitigate by:
    • Running in CI/CD (e.g., GitHub Actions) with caching.
    • Excluding non-critical paths initially (e.g., legacy controllers).
  • False positives/negatives: PSL’s dynamic features (e.g., Psl\Iter\last) may generate noisy type inferences. Mitigate by:
    • Configuring Psalm’s suppress_errors for known edge cases.
    • Using @psalm-suppress annotations sparingly.
  • Dependency bloat: Adding PSL as a dev dependency may increase project size. Justify by measuring runtime validation reduction (e.g., fewer Validator calls).

Key Questions

  1. Prioritization:
    • Which Laravel modules (e.g., API, Eloquent, FormRequests) will benefit most from static validation?
    • Should this replace runtime validation entirely, or coexist temporarily?
  2. Toolchain:
    • How will Psalm results integrate with Laravel’s error reporting (e.g., Horizon, Sentry)?
    • Will IDE feedback (e.g., PHPStorm inspections) be sufficient, or is a custom dashboard needed?
  3. Developer Adoption:
    • What training is needed for teams unfamiliar with PSL/Psalm?
    • How will type annotations be enforced (e.g., CI gates, PR checks)?
  4. Long-term Maintenance:
    • Who will maintain Psalm/PSL compatibility as Laravel evolves?
    • How will breaking changes (e.g., PSL v3) be handled?

Integration Approach

Stack Fit

  • Core Integration:
    • Psalm: Required for static analysis. Configure via psalm.config.php to include PSL types:
      <?php
      return [
          'plugins' => [
              'Psl\Psalm\Plugin',
          ],
          'types' => [
              'Psl' => __DIR__ . '/vendor/php-standard-library/psl/src',
          ],
      ];
      
    • PSL (PHP Standard Library): Core dependency for type definitions. Install via Composer:
      composer require php-standard-library/psl
      
    • Laravel: Target modules where runtime validation exists (e.g., FormRequest, Validator, Eloquent models). Example:
      // Before: Runtime validation
      public function rules() {
          return ['email' => 'required|email'];
      }
      
      // After: Static validation with PSL
      /** @var array{email: string} $validated */
      public function validated(): array {
          $shape = Psl\Type\shape(['email' => Psl\Type\string()]);
          return $shape->coerce($this->input());
      }
      
  • Tooling:
    • CI/CD: Add Psalm to Laravel’s test suite (e.g., GitHub Actions):
      - name: Psalm
        run: vendor/bin/psalm --init --no-cache
      
    • IDE: Configure PHPStorm to use Psalm for inspections (via phpstorm.php config).

Migration Path

  1. Phase 1: Pilot Module
    • Select a low-risk module (e.g., API endpoints) and:
      • Define PSL shapes for request/response contracts.
      • Replace Validator with static checks using @psalm-trace.
      • Verify Psalm passes with minimal false positives.
  2. Phase 2: Domain Models
    • Annotate Eloquent models with PSL shapes (e.g., User):
      class User {
          public function shape(): Psl\Type\Shape {
              return Psl\Type\shape([
                  'id' => Psl\Type\int(),
                  'email' => Psl\Type\string(),
              ]);
          }
      }
      
    • Use Psalm to validate repository/service interactions.
  3. Phase 3: Full Static Validation
    • Replace FormRequest with PSL shapes.
    • Deprecate runtime validation in favor of static checks.
    • Add Psalm to CI/CD with strict error thresholds.

Compatibility

  • Laravel Versions:
    • Laravel 10+: Best fit due to PHP 8.2+ support (e.g., array{...} syntax).
    • Laravel 9: Possible but may require Psalm v4 + plugin v1.x.
  • PSL/Psalm Alignment:
    • Ensure PSL version matches plugin compatibility (e.g., PSL 2.x → plugin ~2.0.0 for Psalm v4).
    • Monitor PSL’s roadmap for breaking changes.
  • Legacy Code:
    • Use @psalm-suppress for unannotated legacy classes.
    • Gradually refactor high-impact paths (e.g., critical API routes).

Sequencing

  1. Pre-requisites:
    • Upgrade Laravel to PHP 8.1+ (required for PSL 2.x).
    • Install Psalm and configure for the project.
  2. Plugin Enablement:
    composer require php-standard-library/psalm-plugin --dev
    vendor/bin/psalm-plugin enable php-standard-library/psalm-plugin
    
  3. Incremental Adoption:
    • Start with new features (avoid touching legacy code).
    • Use feature flags to toggle static vs. runtime validation.
  4. Post-Launch:
    • Measure validation error reduction (e.g., fewer Validator failures in logs).
    • Iterate on Psalm config to reduce false positives.

Operational Impact

Maintenance

  • Psalm Configuration:
    • Requires periodic updates to psalm.config.php (e.g., adding new PSL types).
    • Example: Adding Psl\Type\nullish() support (plugin v2.4.0+).
  • Plugin Updates:
    • Monitor release notes for breaking changes.
    • Test updates against Laravel’s CI pipeline before merging.
  • PSL Maintenance:
    • PSL is actively maintained (last release: 2026-03-17), but Laravel-specific quirks may emerge. Example: Psalm’s handling of Laravel’s Collection methods.

Support

  • Developer Onboarding:
    • Document PSL/Psalm patterns in Laravel’s internal wiki (e.g., "How to define a PSL shape for a FormRequest").
    • Provide code templates for common use cases (e.g., API contracts, Eloquent models).
  • Troubleshooting:
    • Common issues:
      • False positives: Resolve via Psalm’s suppress_errors or plugin config.
      • Performance: Optimize by excluding node_modules or generated files.
      • IDE lag: Use --no-cache for initial runs, then enable caching.
    • Leverage Psalm’s Discord and PSL’s GitHub issues.
  • **Runtime vs. Static
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests