██ ██ ██████ ██████ ██ ██ ██████
████ ████ ██ ██ ██ ██ ██ ██ ██ ██
██ ████ ██ ████████ ██████ █████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██████
Enterprise-grade extensibility meets modern PHP.
Override anything. Intercept any method. Extend any module — all without touching vendor code.
Rapid-development frameworks are great — until you need to customize a third-party module. Enterprise frameworks let you override anything, but demand months of learning.
Marko bridges the gap.
Magento's deep extensibility + Laravel's developer experience + loud, helpful errors.
Marko is a modular PHP 8.5+ framework where everything is a module: your app code, third-party packages, …even the framework. All integration areas follow the same structure and rules. Later modules always win, so your app layer cleanly overrides vendor without patches, forks, or hacks.
- True modularity — Interface and implementation are always separate. Swap any driver (database, cache, mail, queue) without touching a line of application code.
- Preferences — Remap any interface to your own implementation, framework-wide. One line of config replaces an entire class.
- Plugins — Intercept any public method with
beforeandafterhooks. Modify inputs, transform outputs, or add behavior — all without inheritance. - PHP-native configuration — No XML. No YAML. Every route, binding, and plugin is defined in PHP, including full IDE autocompletion and
::classconstants. - Attribute-driven — Routes, plugins, observers, commands, and more are declared with PHP attributes. Discovery is automatic.
- Loud errors — No silent failures. When something goes wrong, Marko tells you exactly what happened, where, and how to fix it.
composer create-project marko/skeleton my-app
cd my-appRegister your first module in app/hello/composer.json:
{
"name": "app/hello",
"autoload": {
"psr-4": {
"App\\Hello\\": "src/"
}
},
"extra": {
"marko": {
"module": true
}
}
}Create a controller at app/hello/src/Controller/HelloController.php:
<?php
declare(strict_types=1);
namespace App\Hello\Controller;
use Marko\Routing\Attributes\Get;
use Marko\Routing\Http\Response;
class HelloController
{
#[Get('/')]
public function index(): Response
{
return new Response('Hello from Marko!');
}
}Start the dev server:
composer global require marko/cli
marko upVisit http://localhost:8000 to see your response.
Everything in Marko is a module. Modules are discovered automatically from three locations, loaded in priority order:
| Location | Purpose | Priority |
|---|---|---|
vendor/ |
Framework & third-party packages | Lowest |
modules/ |
Locally installed third-party modules | Middle |
app/ |
Your application code | Highest |
Later modules always win. Your app/ modules can override controllers, templates, config, and DI bindings from any vendor package — without modifying vendor code.
Preferences — Replace any interface binding:
// app/my-module/module.php
return [
'preferences' => [
PaymentProcessorInterface::class => MyCustomPaymentProcessor::class,
],
];Plugins — Intercept any public method:
#[Plugin(target: OrderService::class)]
class OrderPlugin
{
#[Before]
public function place(Order $order): null
{
// Runs before OrderService::place() — method name matches target
return null;
}
}
#[Plugin(target: OrderService::class)]
class OrderAuditPlugin
{
#[After(method: 'place')]
public function auditPlace(OrderResult $result, Order $order): OrderResult
{
// Custom method name — `method` param maps it to OrderService::place()
return $result;
}
}Observers — React to system events:
#[Observer(event: OrderPlaced::class)]
class SendOrderNotification
{
public function handle(OrderPlaced $event): void
{
// Decoupled, event-driven logic
}
}Marko ships as composable packages — require only what you need. Every package follows an interface/implementation split, so you can swap drivers without changing application code.
| Package | Description |
|---|---|
| core | DI container, module discovery, bootstrap, plugin & preference systems |
| config | PHP-native configuration with dot-notation access |
| env | Environment variable loading |
| routing | Attribute-based HTTP routing with conflict detection |
| cli | Console command system with attribute-driven discovery |
| framework | Full-stack metapackage for rapid setup |
| Package | Description |
|---|---|
| database | Database abstraction, migrations, entity management |
| database-pgsql | PostgreSQL driver |
| database-mysql | MySQL driver |
| Package | Description |
|---|---|
| cache | Cache contracts and manager |
| cache-array | In-memory cache (testing) |
| cache-file | Filesystem cache driver |
| cache-redis | Redis cache driver |
| Package | Description |
|---|---|
| session | Session contracts and manager |
| session-file | File-based sessions |
| session-database | Database-backed sessions |
| Package | Description |
|---|---|
| Mail contracts and manager | |
| mail-log | Log driver (development) |
| mail-smtp | SMTP driver |
| Package | Description |
|---|---|
| queue | Queue contracts and manager |
| queue-sync | Synchronous driver (development) |
| queue-database | Database-backed queue |
| queue-rabbitmq | RabbitMQ driver |
| Package | Description |
|---|---|
| log | PSR-3 logging contracts |
| log-file | File-based log driver |
| Package | Description |
|---|---|
| view | View contracts and template resolution |
| view-latte | Latte template engine integration |
| Package | Description |
|---|---|
| errors | Error handling contracts |
| errors-simple | Minimal error handler |
| errors-advanced | Rich error pages with stack traces |
| Package | Description |
|---|---|
| http | HTTP client contracts |
| http-guzzle | Guzzle HTTP driver |
| Package | Description |
|---|---|
| filesystem | Filesystem contracts |
| filesystem-local | Local filesystem driver |
| filesystem-s3 | Amazon S3 driver |
| Package | Description |
|---|---|
| encryption | Encryption contracts |
| encryption-openssl | OpenSSL driver |
| Package | Description |
|---|---|
| media | Image processing contracts |
| media-gd | GD driver |
| media-imagick | ImageMagick driver |
| Package | Description |
|---|---|
| pubsub | Pub/Sub contracts |
| pubsub-pgsql | PostgreSQL LISTEN/NOTIFY driver |
| pubsub-redis | Redis Pub/Sub driver |
| sse | Server-Sent Events |
| amphp | Async foundation with AMPHP |
| Package | Description |
|---|---|
| authentication | Guard-based authentication |
| authentication-token | Token/API authentication |
| authorization | Policy-based authorization |
| hashing | Password hashing |
| security | Security utilities and middleware |
| cors | Cross-Origin Resource Sharing |
| rate-limiting | Request rate limiting |
| Package | Description |
|---|---|
| blog | Blog module with posts, categories, and tags |
| admin | Admin panel foundation |
| admin-auth | Admin authentication |
| admin-api | Admin REST API |
| admin-panel | Admin UI panel |
| Package | Description |
|---|---|
| api | REST API foundation |
| validation | Input validation |
| pagination | Query result pagination |
| notification | Notification contracts |
| notification-database | Database notification driver |
| translation | Translation contracts |
| translation-file | File-based translations |
| search | Search abstraction |
| scheduler | Task scheduling |
| health | Health check endpoints |
| webhook | Webhook handling |
| dev-server | Local development server |
| Package | Description |
|---|---|
| testing | Test fakes, assertions, and Pest expectations |
| App | Description |
|---|---|
| MarkoTalk | Real-time community chat — dogfoods plugins, preferences, events, SSE, and the admin panel |
- PHP 8.5+
- Composer 2.x
Marko is in active development. The architecture is stable and packages are fully functional, but APIs may evolve before the 1.0 release. We welcome early adopters and feedback.
Marko is developed as a monorepo. All packages live under packages/ and are tested together.
# Clone the repository
git clone https://github.com/marko-php/marko.git
cd marko
# Install dependencies
composer install
# Run tests
./vendor/bin/pest --parallel
# Check code style
./vendor/bin/phpcsVisit marko.build for documentation and updates.
Created by Mark Shust
Marko is open-source software licensed under the MIT License.