A modular monolith framework for Laravel with event-driven architecture, lazy module loading, and built-in multi-tenancy.
π Read the full documentation β
- Event-driven module system - Modules declare interest in lifecycle events and are only loaded when needed
- Lazy loading - Web requests don't load admin modules, API requests don't load web modules
- Multi-tenant isolation - Workspace-scoped data with automatic query filtering
- Actions pattern - Single-purpose business logic classes with dependency injection
- Activity logging - Built-in audit trails for model changes
- Seeder auto-discovery - Automatic ordering via priority and dependency attributes
- HLCRF Layout System - Hierarchical composable layouts (Header, Left, Content, Right, Footer)
composer require host-uk/coreThe service provider will be auto-discovered.
php artisan make:mod CommerceThis creates a module at app/Mod/Commerce/ with a Boot.php entry point:
<?php
namespace Mod\Commerce;
use Core\Events\WebRoutesRegistering;
use Core\Events\AdminPanelBooting;
class Boot
{
public static array $listens = [
WebRoutesRegistering::class => 'onWebRoutes',
AdminPanelBooting::class => 'onAdmin',
];
public function onWebRoutes(WebRoutesRegistering $event): void
{
$event->views('commerce', __DIR__.'/Views');
$event->routes(fn () => require __DIR__.'/Routes/web.php');
}
public function onAdmin(AdminPanelBooting $event): void
{
$event->routes(fn () => require __DIR__.'/Routes/admin.php');
}
}| Event | Purpose |
|---|---|
WebRoutesRegistering |
Public-facing web routes |
AdminPanelBooting |
Admin panel routes and navigation |
ApiRoutesRegistering |
REST API endpoints |
ClientRoutesRegistering |
Authenticated client routes |
ConsoleBooting |
Artisan commands |
McpToolsRegistering |
MCP tool handlers |
FrameworkBooted |
Late-stage initialisation |
Extract business logic into testable, reusable classes:
use Core\Actions\Action;
class CreateOrder
{
use Action;
public function handle(User $user, array $data): Order
{
// Business logic here
return Order::create($data);
}
}
// Usage
$order = CreateOrder::run($user, $validated);Automatic workspace scoping for models:
use Core\Mod\Tenant\Concerns\BelongsToWorkspace;
class Product extends Model
{
use BelongsToWorkspace;
}
// Queries are automatically scoped to the current workspace
$products = Product::all();
// workspace_id is auto-assigned on create
$product = Product::create(['name' => 'Widget']);Track model changes with minimal setup:
use Core\Activity\Concerns\LogsActivity;
class Order extends Model
{
use LogsActivity;
protected array $activityLogAttributes = ['status', 'total'];
}Data-driven layouts with infinite nesting:
use Core\Front\Components\Layout;
$page = Layout::make('HCF')
->h('<nav>Navigation</nav>')
->c('<article>Main content</article>')
->f('<footer>Footer</footer>');
echo $page;Variant strings define structure: HCF (Header-Content-Footer), HLCRF (all five regions), H[LC]CF (nested layouts).
See HLCRF.md for full documentation.
Publish the config file:
php artisan vendor:publish --tag=core-configConfigure module paths in config/core.php:
return [
'module_paths' => [
app_path('Core'),
app_path('Mod'),
],
];php artisan make:mod Commerce # Create a module
php artisan make:website Marketing # Create a website module
php artisan make:plug Stripe # Create a pluginapp/Mod/Commerce/
βββ Boot.php # Module entry point
βββ Actions/ # Business logic
βββ Models/ # Eloquent models
βββ Routes/
β βββ web.php
β βββ admin.php
β βββ api.php
βββ Views/
βββ Migrations/
βββ config.php
- Patterns Guide - Detailed documentation for all framework patterns
- HLCRF Layout System - Composable layout documentation
composer test- PHP 8.2+
- Laravel 11+
EUPL-1.2 - See LICENSE for details.