otatechie/laravel-spotlight

A lighthouse-style diagnostics tool that scans Laravel applications for performance, security, and architecture issues.

Maintainers

Package info

github.com/otatechie/laravel-spotlight

pkg:composer/otatechie/laravel-spotlight

Fund package maintenance!

otatechie

Statistics

Installs: 50

Dependents: 0

Suggesters: 0

Stars: 9

Open Issues: 2

v1.1.0 2026-01-23 06:05 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.

Latest Version on Packagist GitHub Tests Code Style Total Downloads

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 found
  • 2 - Medium or high severity issues found
  • 3 - 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 use config()
  • Queries in Blade: Detects database queries in Blade templates
  • Mass Assignment Protection: Checks for missing $fillable or $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 rules
  • custom_rules - Register your own custom rules
  • severity_threshold - Filter rules by severity level
  • thresholds - Customize rule-specific thresholds (e.g., controller line limits)
  • debug - Enable debug logging
  • error_handling - Control error handling behavior

See Examples & Configuration for more details.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Documentation

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.