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 Laravel Package

vimeo/psalm

Psalm is a PHP static analysis tool that finds type issues, bugs, and dead code before runtime. It supports gradual typing via annotations, powerful checks, and configurable rules to improve code quality in applications and libraries.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel Developers

  1. Installation Add Psalm to your Laravel project via Composer:

    composer require vimeo/psalm --dev
    

    Initialize Psalm configuration by running:

    vendor/bin/psalm --init
    

    This generates a psalm.xml file in your project root.

  2. First Run Analyze your entire project with default settings:

    vendor/bin/psalm
    

    For a quick check of a single file (e.g., app/Services/UserService.php):

    vendor/bin/psalm --file app/Services/UserService.php
    
  3. Integrate with Laravel’s CI Add a Psalm step to your GitHub Actions (.github/workflows/psalm.yml):

    - name: Run Psalm
      run: vendor/bin/psalm --no-cache
    
  4. Key Configurations Update psalm.xml to include Laravel-specific paths:

    <projectFiles>
        <directory name="app" />
        <directory name="config" />
        <directory name="database/seeds" />
        <directory name="routes" />
    </projectFiles>
    

Implementation Patterns

Daily Workflow for Laravel Developers

  1. Pre-Commit Hooks Use psalm with --report=github for PR-friendly output:

    composer global require laravel/pint
    composer global require dealerdirect/phpcodesniffer-composer-installer
    composer require --dev dealerdirect/phpcodesniffer-composer-installer
    

    Add to .git/hooks/pre-commit:

    #!/bin/sh
    vendor/bin/psalm --report=github --output-format=github
    
  2. Laravel-Specific Annotations Annotate Eloquent models and services for better type inference:

    use Psalm\Type\Union;
    
    /**
     * @psalm-import-type UserId from \App\Models\User
     * @psalm-import-type UserData from \App\DTO\UserData
     */
    class UserService {
        /**
         * @param UserId $userId
         * @return UserData
         */
        public function getUserData(string $userId): UserData { ... }
    }
    
  3. Security Analysis Enable taint analysis for input validation:

    vendor/bin/psalm --issues=Security
    

    Annotate controllers to mark tainted data:

    /**
     * @psalm-suppress MixedArgument
     * @psalm-suppress MixedReturnStatement
     */
    public function store(Request $request) {
        $input = $request->input(); // Marked as tainted
        $sanitized = $this->sanitize($input); // Should be pure
    }
    
  4. Plugin Integration Use Psalm’s plugin API (v7+) to extend functionality. Example: Create a custom plugin for Laravel’s HasFactory trait:

    // plugins/LaravelFactoryPlugin.php
    namespace PsalmPlugin\Laravel;
    
    use Psalm\Plugin\PluginEntryPointInterface;
    
    class LaravelFactoryPlugin implements PluginEntryPointInterface {
        public function __invoke(): void {
            // Register stubs or custom rules
        }
    }
    

    Register in psalm.xml:

    <pluginClass>PsalmPlugin\Laravel\LaravelFactoryPlugin</pluginClass>
    
  5. CI Feedback Use --stats to track Psalm’s effectiveness:

    vendor/bin/psalm --stats --output-format=json > psalm-stats.json
    

    Parse JSON in CI for trend analysis.


Gotchas and Tips

Common Pitfalls

  1. False Positives with Laravel’s Magic Methods Psalm may flag Arrayable, Jsonable, or Serializable as undefined. Add stubs or suppress:

    /**
     * @psalm-suppress MixedReturnType
     */
    public function toArray(): array { ... }
    
  2. Dynamic Properties in Eloquent Psalm doesn’t recognize dynamic properties (e.g., $model->dynamicProp). Use @property annotations:

    /**
     * @property string $dynamicProp
     */
    class DynamicModel extends Model { ... }
    
  3. Closure Type Inference Avoid callable for Laravel closures. Use specific types:

    // Bad: Ambiguous
    $callback = function () {};
    
    // Good: Explicit
    $callback = fn(): void => null;
    
  4. JIT Performance Disable JIT for CI (enabled by default in v7+):

    vendor/bin/psalm --no-jit
    
  5. Plugin Conflicts Ensure plugins are compatible with your Psalm version. Check composer.json for version constraints.


Debugging Tips

  1. Isolate Issues Use --file to narrow down problematic files:

    vendor/bin/psalm --file app/Http/Controllers/UserController.php --issues=TypeError
    
  2. Snippets for Context Add --show-snippets to see code context:

    vendor/bin/psalm --show-snippets --issues=UndefinedClass
    
  3. Custom Error Levels Adjust ERROR_LEVEL in psalm.xml to focus on critical issues:

    <errorLevel>3</errorLevel> <!-- Only show errors/warnings -->
    
  4. Autofix Common Issues Use --alter to auto-fix MissingReturnType, MissingParamType, etc.:

    vendor/bin/psalm --alter --issues=MissingReturnType,MissingParamType
    
  5. Laravel-Specific Suppressions Suppress issues for entire directories (e.g., vendor):

    <suppressErrors>
        <error name="MissingDocblockType">...</error>
        <error name="MixedAssignment">...</error>
    </suppressErrors>
    

Pro Tips

  1. Leverage @psalm-pure for Security Mark pure functions to eliminate taint analysis false positives:

    /**
     * @psalm-pure
     */
    function sanitizeInput(string $input): string { ... }
    
  2. Use @psalm-mutation-free for Services Improve mutability analysis in Laravel services:

    /**
     * @psalm-mutation-free
     */
    class UserService { ... }
    
  3. Custom Stubs for Third-Party Packages Generate stubs for unsupported packages (e.g., spatie/laravel-permission):

    vendor/bin/psalm --generate-stubs src
    
  4. IDE Integration Configure PhpStorm to use Psalm’s inspection engine:

    • Install the Psalm plugin.
    • Set PHPSTORM env var to 1 for macOS/Linux:
      export PHPSTORM=1
      
  5. Performance Optimization Cache results in CI:

    vendor/bin/psalm --cache-globals
    

    Exclude node_modules and vendor from analysis:

    <projectFiles>
        <exclude-name>node_modules</exclude-name>
        <exclude-name>vendor</exclude-name>
    </projectFiles>
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope