syscage/laravel-plugin

A WordPress-style plugin framework for Laravel applications.

Maintainers

Package info

github.com/syscage/laravel-plugin

pkg:composer/syscage/laravel-plugin

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

dev-main 2026-07-26 07:28 UTC

This package is auto-updated.

Last update: 2026-07-26 08:41:36 UTC


README

Latest Version License PHP Version Laravel

A WordPress-style plugin framework for Laravel 12+ applications. syscage/laravel-plugin turns a plugins/ directory in your host application into a set of independently discoverable, installable, and toggleable Laravel packages — each with its own routes, views, translations, migrations, config, assets, and console commands — without ever running composer dump-autoload.

This package does not manage your application's modules or its own business logic; it manages the plugins that live inside plugins/ in your host application.

Installation

composer require syscage/laravel-plugin
php artisan vendor:publish --tag=plugin-config
php artisan vendor:publish --tag=plugin-migrations
php artisan migrate

Creating a plugin

php artisan make:plugin BlogPost --description="Blog integration"
php artisan plugin:install blog-post

make:plugin scaffolds the full plugin directory structure:

plugins/blog-post/
├── src/
│   ├── app/
│   │   ├── Http/{Controllers,Middleware,Requests}/
│   │   ├── Models/
│   │   └── Providers/BlogPluginPluginServiceProvider.php
│   ├── config/config.php
│   ├── database/{migrations,factories,seeders}/
│   ├── lang/
│   ├── public/
│   ├── resources/{css,js,views}/
│   ├── routes/{web,api,console}.php
│   └── Plugin.php
├── composer.json
├── plugin.json
└── README.md

plugin.json is the plugin's manifest — name, alias, version, its service provider's class name, dependencies, permissions, and sidebar contributions. src/Plugin.php extends Syscage\Plugin\AbstractPlugin and exposes every path a manager or command needs ($plugin->viewPath(), $plugin->migrationPath(), ...) plus lifecycle hooks (install(), uninstall(), enable(), disable(), update()) you can override. The plugin's own service provider extends Syscage\Plugin\PluginServiceProviderBase, which auto-wires routes, views, translations, migrations, config, assets, and console commands for you.

Plugin lifecycle

php artisan plugin:list                    # every discovered plugin and its state
php artisan plugin:info blog-post        # detailed info about one plugin
php artisan plugin:install blog-post     # creates the DB record, assigns a UUID
php artisan plugin:enable blog-post
php artisan plugin:disable blog-post
php artisan plugin:update blog-post      # syncs the DB to the current manifest version
php artisan plugin:uninstall blog-post
php artisan plugin:doctor                  # health-check every plugin's providers/dependencies
php artisan plugin:publish blog-post     # (re-)publish a plugin's public assets

requires/conflicts in plugin.json are validated (including semver version constraints) before install/enable, and a plugin's loading order is resolved topologically by its dependencies, then by priority.

Caching

php artisan plugin:discover   # rebuild the discovery cache from disk
php artisan plugin:cache      # rebuild discovery + sidebar + frontend caches
php artisan plugin:clear      # remove all compiled caches

Generating a new plugin (make:plugin) automatically invalidates the discovery cache, so the next Artisan process picks it up without a manual plugin:discover.

Friendly generator aliases

Every plugin-scoped counterpart of Laravel's own generators and database commands is available, redirecting output into the target plugin instead of the host application:

php artisan make:model-plugin blog-post Post -mfs
php artisan make:controller-plugin blog-post PostController --resource
php artisan migrate-plugin blog-post
php artisan db:seed-plugin blog-post
php artisan route:list-plugin blog-post
php artisan test-plugin blog-post

See prompt.md for the full list — every make:*, migrate*, db:*, route:*, config:cache, view:cache, event:cache, vendor:publish, optimize, and queue:work command has a *-plugin alias supporting the same arguments and options as the original.

Frontend integration

For React/Vue/Inertia hosts (auto-detected from package.json, or set explicitly via plugin.frontend in the published config), plugin:cache generates bootstrap/cache/plugins.ts containing every plugin's page component imports (from resources/js/Pages), routes, and sidebar entries — read by your frontend build instead of editing app.tsx/app.ts directly.

Architecture

Every framework responsibility is its own single-purpose class behind an interface, resolved via the container — see src/Contracts/. Plugin Discovery, the Plugin Registry, the Dependency Resolver, the Plugin Manager/Loader/Lifecycle, and each resource manager (Route, View, Translation, Migration, Config, Asset, Command) can each be swapped independently. The package reuses Laravel's own building blocks throughout — its Router, Translator, Migrator, config repository, filesystem, and generator commands — rather than duplicating them.

Testing

composer install
vendor/bin/phpunit