Safely detect and remove unused CSS, JS, SCSS, images, and other assets from your Laravel applications. Works seamlessly with Laravel, Laravel Vue, Laravel React, Inertia.js, and Livewire projects
Features
Smart Detection - Scans your entire Laravel project for unused assets
Safe Deletion - Creates backups before removing any files
Selective Cleaning - Choose specific asset types (JS, CSS, images, fonts, etc.)
Detailed Reports - See exactly what will be deleted and why
Debug Mode - Investigate why files are marked as used or unused
Fast Scanning - Efficiently processes large projects
Framework Agnostic - Works with Mix, Vite, plain webpack, and more
Protected Files - Never accidentally delete important files
Strict Matching - Avoids false positives with intelligent pattern matching
Wildcard Support (New in v1.0.1) - Use wildcards in directory patterns
Requirements
PHP 8.2 or higher
Laravel 9.x, 10.x, 11.x, or 12.x
Composer
Installation
composer require tarunkorat/laravel-asset-cleanerPublish Configuration
php artisan vendor:publish --tag=asset-cleaner-configThis creates config/asset-cleaner.php where you can customize settings.
Usage
Basic Commands
Scan for Unused Assets
# Scan all asset types
php artisan assets:scan
# Scan specific types
php artisan assets:scan --type=js --type=css
php artisan assets:scan --type=img
# Show detailed information
php artisan assets:scan --details
# Output as JSON
php artisan assets:scan --jsonDelete Unused Assets
# Dry run (preview what will be deleted)
php artisan assets:delete --dry-run
# Delete with confirmation
php artisan assets:delete
# Delete without confirmation
php artisan assets:delete --force
# Delete without backup
php artisan assets:delete --no-backup --force
# Delete specific types
php artisan assets:delete --type=js --type=cssDebug Mode
# Debug specific file
php artisan assets:debug resources/images/logo.png
# Show all found assets
php artisan assets:debug --show-all
# Show all reference patterns
php artisan assets:debug --show-refs
# Debug specific type
php artisan assets:debug --type=js --show-allExample Workflow
# Step 1: Scan for unused assets
php artisan assets:scan
# Output:
# Found 15 unused asset(s):
# π¦ js (5 files)
# π resources/js/old-component.js (2.5 KB)
# π public/js/legacy-script.js (8.2 KB)
# π¦ css (4 files)
# π resources/css/unused-styles.css (3.1 KB)
# π¦ img (6 files)
# π public/images/old-logo.png (45 KB)
# Step 2: Preview deletion
php artisan assets:delete --dry-run
# Step 3: Delete unused assets
php artisan assets:delete
# Step 4: Verify backup created
# Backup location: storage/asset-cleaner-backup/2024-11-12_153045/Configuration
Edit config/asset-cleaner.php:
return [
// Specify which asset types to clean by default
'clean_types' => 'all', // or ['js', 'css', 'img']
// Enable strict matching (recommended)
'strict_matching' => true,
// Define asset types and their locations
'asset_types' => [
'js' => [
'directories' => [
'resources/js',
'public/js',
'public/js/*', // β¨ NEW: Wildcard support
],
'extensions' => ['js', 'jsx', 'ts', 'tsx', 'vue', 'mjs'],
],
'css' => [
'directories' => [
'resources/css',
'resources/sass',
'public/css',
'public/css/*', // β¨ NEW: Scans css/vendor, css/admin, etc.'
],
'extensions' => ['css', 'scss', 'sass', 'less'],
],
'img' => [
'directories' => [
'resources/images',
'public/images',
'public/assets/**', // β¨ NEW: Recursive wildcard
],
'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'ico'],
],
// ... more types
],
// Directories to scan for asset references
'scan_directories' => ['app', 'resources/views', 'resources/js', 'routes'],
// Files that should never be deleted
'protected_files' => [
'resources/js/app.js',
'resources/css/app.css',
],
// Backup settings
'backup_directory' => storage_path('asset-cleaner-backup'),
'create_backup' => true,
];How It Works
Detection Process
Scans Asset Directories - Finds all assets in configured directories
Searches for References - Looks for asset usage in:
Blade templates (
asset(),<img src>,<script>,<link>)JavaScript files (imports, requires, dynamic imports)
CSS files (
url(),@import, background images)PHP controllers (
Image::make(),public_path(),Storage::url())Vue/React components (import statements, src attributes)
Build configs (webpack.mix.js, vite.config.js, package.json)
Strict Matching - Only matches complete filenames with extensions
Safe Deletion - Creates timestamped backups before removal
Wildcard Directory Patterns (New in v1.0.1)
You can now use wildcard patterns in your directory configuration for more flexible asset scanning.
Single Level Wildcard (*) Single Level Wildcard (*)
'directories' => [
'public/css/*', // Scans: public/css/vendor, public/css/admin, public/css/themes
]
Example structure:
public/css/
βββ app.css β
Scanned
βββ vendor/
β βββ bootstrap.css β
Scanned
βββ admin/
βββ style.css β
Scanned
**Recursive Wildcard () Scans the directory and ALL subdirectories recursively:
'directories' => [
'public/assets/**', // Scans everything under public/assets
]
Example structure:
public/assets/
βββ css/
β βββ app.css β
Scanned
β βββ vendor/
β βββ bootstrap.css β
Scanned
βββ js/
β βββ app.js β
Scanned
βββ images/
βββ logo.png β
Scanned
What Gets Detected
These patterns are detected:
// Blade templates
<img src="{{ asset('images/logo.png') }}">
<script src="{{ mix('js/app.js') }}"></script>
// JavaScript
import Logo from './images/logo.png';
require('./components/Header.vue');
// CSS
background-image: url('../images/banner.jpg');
@import 'components/button.css';
// PHP Controllers
$image = Image::make(public_path('images/product.jpg'));
return asset('images/logo.png');False positives avoided:
File named
error.svgwon't match word "error" in codetest.jswon't match variable named "test"Strict boundary checking prevents partial matches
Safety Features
β Automatic Backups - All deleted files are backed up with timestamps
β Protected Files - Important files (app.js, app.css) are never deleted
β Dry Run Mode - Preview changes before applying them
β Confirmation Prompts - Asks for confirmation before deletion
β Verification - Checks if files were actually deleted
β Error Logging - Failed deletions are logged for review
Use Cases
Clean Up After Refactoring
# After removing old components
php artisan assets:scan --type=js
php artisan assets:delete --type=js --dry-runOptimize Images
# Find unused images
php artisan assets:scan --type=img
php artisan assets:delete --type=imgCI/CD Integration
# In your deployment script
php artisan assets:scan --json > unused-assets-report.jsonBefore Production Deploy
# Clean up everything
php artisan assets:scan
php artisan assets:delete --forceTroubleshooting
Files Not Being Detected as Unused
# Debug specific file
php artisan assets:debug resources/js/MyComponent.vue
# This will show:
# - Where the file is located
# - What references it (if any)
# - Why it's marked as used/unusedFiles Won't Delete
Common causes:
File permissions (run as administrator on Windows)
File is open in an editor
Antivirus blocking deletion
Solution:
# Check what failed
# Check Laravel logs: storage/logs/laravel.log
# Try with elevated permissions (Windows)
# Run PowerShell as Administrator
php artisan assets:delete --forceFalse Positives
If files are incorrectly marked as used:
// config/asset-cleaner.php
'strict_matching' => true, // Ensure this is enabledRestore from Backup
# Backups are in storage/asset-cleaner-backup/
# Each run creates a timestamped folder
# To restore:
cp -r storage/asset-cleaner-backup/2024-11-12_153045/* ./You can learn more about this package, get full installation instructions, and view the source code on GitHub.










