Dead code
Find unused classes, methods, routes, views, and imports.From its SKILL.md
npx -y skills add edulazaro/laraclaude --skill dead-codeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.2 KB, as published. Nobody here has run it
Dead Code Detection
Find unused classes, methods, routes, Blade views, and import statements through static analysis.
Subcommands
| Subcommand | Description |
|---|---|
| (no argument) | Scan the entire project for dead code. Read-only report. |
clean | Remove confirmed dead code. Asks for confirmation before each removal. |
clean --dry-run | Show what would be removed without deleting anything. |
[directory] | Analyze a specific directory for dead code. Read-only. |
Detection Rules
1. Unused Classes
What to detect:
Classes in app/ that are never instantiated, referenced, imported, or used anywhere else in the codebase.
How to scan:
- Use
Globto find all PHP classes inapp/(excluding vendor). - For each class, extract the fully qualified class name.
- Use
Grepto search the entire codebase for:use App\ClassName;import statementsClassName::static callsnew ClassName(instantiationClassName::classreferences (in route files, service providers, model arrays, etc.)- Type hints:
function foo(ClassName $param)
- Exclude self-references (the class referencing itself).
- Check special registration locations:
app/Providers/*.phpfor service provider registrationsconfig/*.phpfor class references in configroutes/*.phpfor controller referencescomposer.jsonfor autoload references- Model
$actions,$castsarrays for action/enum classes
Classes to skip (never flag as unused):
- Models (may be used via Eloquent, route model binding, morph maps)
- Service providers (registered in
config/app.phporbootstrap/providers.php) - Middleware (registered in kernel or route groups)
- Commands (auto-discovered by Laravel)
- Observers (registered in service providers)
- Policies (auto-discovered by naming convention)
Severity: Medium
Clean action: Delete the class file after confirmation.
2. Unused Public Methods
What to detect: Public methods on classes that are never called from outside the class.
How to scan:
- For each class, extract all public method names.
- Use
Grepto search for calls to each method:->methodName(instance calls::methodName(static calls'methodName'string references (for dynamic dispatch, route actions, etc.)
- Exclude framework-convention methods that are called implicitly:
mount(),render(),boot(),booted()(Livewire/Eloquent)handle()(Jobs, Actions, Commands)up(),down()(Migrations)rules(),messages()(Validation)authorize()(Form Requests)- Relationship methods (called by Eloquent magic)
- Scope methods (called via
Model::scopeName()) - Accessor/mutator methods
Severity: Low (methods may be used dynamically or reserved for future use)
Clean action: Remove the method after confirmation. Show the full method body before deletion so the user can review.
3. Unused Routes
What to detect:
Routes defined in routes/*.php that are never linked to via route(), url(), or action() helpers.
How to scan:
- Use
Readto parse all route files and extract named routes. - For each named route, use
Grepto search for:route('route.name')callsroute('route.name',calls with parametersRoute::has('route.name')checks- Links in Blade:
href="{{ route('route.name') }}" - Redirects:
redirect()->route('route.name')
- Also check for unnamed routes by searching for the URI pattern.
- Exclude API routes that may be called by external clients.
Severity: Low (routes may be used by external systems or planned for future use)
Clean action: Comment out or remove the route definition after confirmation.
4. Unused Blade Views
What to detect:
Blade view files in resources/views/ that are never rendered.
How to scan:
- Use
Globto find allresources/views/**/*.blade.phpfiles. - For each view, derive the view name (e.g.,
resources/views/livewire/properties/index.blade.php->livewire.properties.index). - Use
Grepto search for references:view('view.name')orview("view.name")@include('view.name')or@include("view.name")@extends('view.name')@livewire('component.name')<livewire:component-name />@component('view.name')<x-component-name(for component views)
- For Livewire Volt components, they are auto-discovered by path -- check if a route or
@livewiredirective references them.
Views to skip (never flag as unused):
- Layout files in
resources/views/layouts/orresources/views/components/layouts/ - Component views in
resources/views/components/(used via<x-name>) - Error pages in
resources/views/errors/ - Email templates in
resources/views/mail/orresources/views/emails/
Severity: Low
Clean action: Delete the view file after confirmation.
5. Unused Imports (use statements)
What to detect:
use statements at the top of PHP files that import classes never referenced in the file body.
How to scan:
- For each PHP file, extract all
useimport statements. - For each import, extract the class name (last segment of the namespace).
- Search the file body (excluding the use statement itself) for:
- The class name as a type hint, return type, or standalone reference
- The class name in PHPDoc comments (
@param ClassName) - Static calls
ClassName:: - Instantiation
new ClassName
- Flag imports where the class name is not found in the file body.
Severity: Very Low (cosmetic, no runtime impact)
Clean action: Remove the unused use statement.
Report Format
DEAD CODE ANALYSIS
===================
UNUSED CLASSES (3 found)
-------------------------
1. App\Services\LegacyImportService
File: app/Services/LegacyImportService.php
Reason: Zero references in codebase
Lines: 145
2. App\Actions\Property\OldExportAction
File: app/Actions/Property/OldExportAction.php
Reason: Zero references in codebase (not in model $actions)
Lines: 67
UNUSED ROUTES (2 found)
-------------------------
1. Route: 'admin.legacy.import' (GET /admin/legacy/import)
File: routes/app.php:142
Reason: No route() call found
UNUSED VIEWS (1 found)
------------------------
1. View: livewire.admin.legacy-import
File: resources/views/livewire/admin/legacy-import.blade.php
Reason: No @livewire or route reference
UNUSED IMPORTS (15 found)
--------------------------
1. app/Http/Controllers/PropertyController.php:8
use App\Models\Office; (never referenced)
2. app/Services/SearchService.php:5
use Illuminate\Support\Str; (never referenced)
...
SUMMARY
========
Category | Found | Total Lines
------------------|-------|------------
Unused classes | 3 | 312
Unused methods | 7 | 89
Unused routes | 2 | -
Unused views | 1 | 45
Unused imports | 15 | 15
Total dead code | 28 | ~461 lines
Clean Mode
In clean mode, process each category in order (classes, methods, routes, views, imports):
- Show the item to be removed with full context.
- Ask for confirmation before each removal.
- For classes and views: delete the file.
- For methods: use
Editto remove the method from the class. - For routes: use
Editto remove or comment out the route. - For imports: use
Editto remove theusestatement.
Notes
- False positives are expected. Classes may be used via:
- Dynamic instantiation (
app($className)) - Config references (
config('key')resolving to a class) - Service container bindings
- Event listeners registered as strings
- Morph maps in
AppServiceProvider
- Dynamic instantiation (
- Always err on the side of caution. When in doubt, flag but do not auto-clean.
- Methods on interfaces/contracts are never "unused" even if only called via the interface.
- Test files reference application classes but should not be considered "usage" for dead code purposes (a class only used in tests may still be dead).
- Blade views can be referenced dynamically:
view("livewire.{$type}.{$action}")-- these are not detectable statically.