otatechie / laravel-spotlight
A lighthouse-style diagnostics tool that scans Laravel applications for performance, security, and architecture issues.
Fund package maintenance!
Requires
- php: ^8.1
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
This package is auto-updated.
Last update: 2026-04-02 06:28:15 UTC
README
A lighthouse-style diagnostics tool that scans Laravel applications for performance, security, and architecture issues. Built with a modular rule system that makes it easy to extend and customize.
What is Spotlight?
Spotlight is NOT:
- ❌ Code formatter - Spotlight doesn't format or fix your code style
- ❌ Linter - Spotlight doesn't enforce coding standards or syntax rules
- ❌ Debugger - Spotlight doesn't debug runtime errors or exceptions
Spotlight IS:
- ✅ Diagnostic Scanner - Identifies potential issues before they become problems
- ✅ Best Practices Advisor - Points out improvements based on Laravel best practices
- ✅ Performance Analyzer - Finds performance bottlenecks and optimization opportunities
- ✅ Security Auditor - Flags security vulnerabilities and misconfigurations
- ✅ Architecture Mentor - Gives gentle tips on code organization
- ✅ Guidance Tool - Just suggestions, you're in control
Laravel Spotlight helps you identify and fix issues in your Laravel application before they become problems. It scans your application for:
- Performance Issues: Missing caches, inefficient queue drivers, N+1 queries
- Security Vulnerabilities: Debug mode in production, insecure configurations
- Architecture Problems: Fat controllers, route closures, code organization
Philosophy
Spotlight provides guidance, not enforcement. No shaming, no judgment.
Laravel Spotlight is a friendly mentor, not an angry linter. We help you improve your code with gentle suggestions, not shame or rigid rules.
- No Shaming - We use "could improve" and "consider" instead of "MUST fix" or "WRONG"
- User Control - Every rule can be disabled if it doesn't fit your project
- Objective vs Advisory - Security/performance issues are flagged firmly; architecture suggestions are gentle
- Fast & Lightweight - Executes in < 1 second using lightweight checks
See Why Spotlight? to see how it compares to other tools.
Features
- 🔍 20 Built-in Rules - Covers performance, security, and architecture
- 🧩 Modular Rule System - Easy to extend with custom rules (auto-detection eliminates boilerplate)
- ⚙️ Full User Control - Enable/disable any rule that doesn't fit your project
- 🎯 Severity Scoring - 4-level severity system with health score calculation
- ⚡ Lightning Fast - Executes in < 1 second
- 🛡️ Error Handling - One rule failure won't crash the entire scan
- 📊 Multiple Output Formats - Table and JSON output formats
- 🛠️ Developer Tools - Rule generator, rule listing, CI/CD exit codes
- 📖 Documentation URLs - Rules can link to detailed documentation
- 🎨 PHP 8.1+ Enums - Type-safe severity and rule type enums
Installation
You can install the package via composer:
composer require otatechie/laravel-beacon
You can publish the config file with:
php artisan vendor:publish --tag="spotlight-config"
The config file lets you:
- Enabling/disabling specific rules
- Registering custom rules
- Setting severity threshold
- Configuring error handling
- Enabling debug mode
See the configuration documentation for details.
Usage
Basic Scanning
Run a full scan of your application:
php artisan spotlight:scan
Scan Specific Categories
Scan only performance issues:
php artisan spotlight:scan --category=performance
Scan multiple categories:
php artisan spotlight:scan --category=performance --category=security
Get JSON Output
php artisan spotlight:scan --format=json
Filter by Severity
Only show critical issues:
php artisan spotlight:scan --severity=critical
Exit Codes for CI/CD
Spotlight uses exit codes for CI/CD integration:
Exit Code Mapping:
0- No issues found (clean scan)1- Only low severity issues found2- Medium or high severity issues found3- Critical issues found
Usage Examples:
# Default: Auto-detect exit code based on severity php artisan spotlight:scan # Fail only on critical issues php artisan spotlight:scan --fail-on=critical # Fail on high or critical issues php artisan spotlight:scan --fail-on=high # Fail on any issues (including low) php artisan spotlight:scan --fail-on=low
GitHub Actions Example:
- name: Run Spotlight Scan run: php artisan spotlight:scan || exit 1
List Available Rules
See all available rules:
php artisan spotlight:rules
Get details about a specific rule:
php artisan spotlight:rules --rule=performance.config-cache
Create Custom Rules
Generate a new rule class:
php artisan spotlight:make-rule MyCustomRule --category=performance --type=objective
This creates a rule class with proper structure and auto-registers it.
Programmatic Usage
use Otatechie\Spotlight\Spotlight; $spotlight = app(Spotlight::class); $results = $spotlight->scan(['performance', 'security']); // Access results $summary = $results['summary']; $categories = $results['categories'];
Rule Types & Severity
Spotlight uses a two-dimensional classification system:
Rule Types
-
Objective Rules (
type: 'objective') - Firm recommendations based on hard facts- Examples: Debug enabled, config not cached, insecure cookies
- Spotlight can be firm with these
-
Advisory Rules (
type: 'advisory') - Gentle suggestions based on best practices- Examples: Fat controllers, route closures, folder structure
- Spotlight should be gentle with these
Severity Levels
Spotlight uses 4 severity levels with numeric weights for scoring:
| Level | Weight | Purpose |
|---|---|---|
critical |
100 | Production-breaking / security risk |
high |
70 | Serious performance or stability issue |
medium |
40 | Performance issues or config problems |
low |
10 | Minor improvement / suggestion |
Health Score: Spotlight calculates a health score (0-100%) based on severity weights, giving you a quick overview of your application's status.
Category-Based Defaults: If a rule doesn't specify severity, it inherits from its category:
- Security rules default to
high - Performance rules default to
medium - Architecture rules default to
low
All rules can be disabled in config/spotlight.php if they don't apply to your project.
Built-in Rules
Performance Rules
- Config Cache: Checks if config cache is enabled in production
- Route Cache: Checks if route cache is enabled in production
- Queue Sync Driver: Warns about sync queue driver in production
- View Cache: Checks if view cache is enabled
- Event Cache: Checks if event cache is enabled
- N+1 Queries: Detects potential N+1 query problems
- Missing Chunking: Identifies large dataset operations without chunking
Security Rules
- App Debug Enabled: Critical check for debug mode in production
- Insecure Session Driver: Warns about insecure session drivers
- HTTPS Enforcement: Checks if HTTPS is properly enforced
- Cookie Secure Flag: Verifies secure cookie configuration
Architecture Rules
- Route Closure Usage: Detects route closures preventing caching
- Large Controller Detection: Identifies controllers exceeding configurable line threshold
- Missing API Resources: Detects API routes without API resources
- Missing Form Requests: Detects controllers using inline validation instead of Form Requests
- Direct ENV Usage: Finds direct
env()calls that should useconfig() - Queries in Blade: Detects database queries in Blade templates
- Mass Assignment Protection: Checks for missing
$fillableor$guarded - Logic in Routes: Identifies complex logic in route files
- JS/CSS in Blade: Finds inline JavaScript and CSS in templates
Creating Custom Rules
Want to add your own rules? It's easy. Check out the Creating Rules Guide for the full walkthrough.
Quick Example
Here's how simple it is:
<?php namespace App\Spotlight\Rules\Performance; // Category auto-detected from namespace! use Otatechie\Spotlight\Rules\AbstractRule; class MyCustomRule extends AbstractRule { // Only define what's different - everything else is auto-detected! protected ?string $severity = 'medium'; // Or leave null for category-based default protected string $description = 'Checks for a specific issue'; protected ?string $documentationUrl = 'https://example.com/docs/my-rule'; // id: auto-generated as 'performance.my-custom' // category: auto-detected as 'performance' from namespace // name: auto-generated as 'My Custom' from class name // severity: defaults to 'medium' (performance category default) public function scan(): array { if ($issueFound) { return $this->suggest( 'Issue description', ['recommendation' => 'How to fix it'] ); } return $this->pass('Everything looks good!'); } }
Register it in config/spotlight.php:
return [ 'custom_rules' => [ \App\Spotlight\Rules\MyCustomRule::class, ], ];
Configuration
Publish the config file:
php artisan vendor:publish --tag="spotlight-config"
Key configuration options:
enabled_rules- Enable/disable specific rulescustom_rules- Register your own custom rulesseverity_threshold- Filter rules by severity levelthresholds- Customize rule-specific thresholds (e.g., controller line limits)debug- Enable debug loggingerror_handling- Control error handling behavior
See Examples & Configuration for more details.
Changelog
Please see CHANGELOG for more information on what has changed recently.
Documentation
- Creating Custom Rules - Guide to creating your own rules
- Examples & Configuration - Usage examples and configuration options
- Laravel Best Practices - Sources and rationale behind rules
Contributing
Contributions are welcome! Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
Laravel Trademark Disclaimer
Laravel is a trademark of Taylor Otwell. This package is not officially associated with Laravel or Taylor Otwell. The "laravel-" prefix in the package name is used to indicate compatibility with the Laravel framework and follows community naming conventions.