Marko
██ ██ ██████ ██████ ██ ██ ██████ ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ████████ ██████ █████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██████
Enterprise-grade extensibility meets modern PHP.
Override anything. Intercept any method. Extend any module — all without touching vendor code.
Documentation, guides, and tutorials at marko.build/docs.
#Why Marko?
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.
#What makes Marko different
- 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, layouts, 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.
#Watch the Introduction
Learn what Marko is, why it exists, and how it works in this short video overview.
Introducing Marko: The Truly Modular PHP Framework
#Quick Start
composer create-project marko/skeleton my-app
cd my-app
Register 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 up
Visit http://localhost:8000 to see your response.
#Module System
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.
#Extending vendor behavior
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 } }
#Packages
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.
#Core
| 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 |
| roadrunner | RoadRunner application server driver |
| cli | Console command system with attribute-driven discovery |
| framework | Full-stack metapackage for rapid setup |
#Database
| Package | Description |
|---|---|
| database | Database abstraction, migrations, entity management |
| database-pgsql | PostgreSQL driver |
| database-mysql | MySQL driver |
| database-readwrite | Read/write connection splitting |
#Caching
| Package | Description |
|---|---|
| cache | Cache contracts and manager |
| cache-array | In-memory cache (testing) |
| cache-file | Filesystem cache driver |
| cache-redis | Redis cache driver |
#Full-Page Caching
| Package | Description |
|---|---|
| page-cache | Full-page HTTP cache contracts and middleware |
| page-cache-file | File-based page cache driver |
| page-cache-entity | Auto-purge page cache tags on entity save/delete |
#Session
| 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 |
#Queue
| Package | Description |
|---|---|
| queue | Queue contracts and manager |
| queue-sync | Synchronous driver (development) |
| queue-database | Database-backed queue |
| queue-rabbitmq | RabbitMQ driver |
#Logging
#Views, Templates & Layout
| Package | Description |
|---|---|
| view | View contracts and template resolution |
| view-latte | Latte template engine integration |
| view-twig | Twig template engine integration |
| layout | Attribute-driven layout system with slot-based component composition |
#Error Handling
| Package | Description |
|---|---|
| errors | Error handling contracts |
| errors-simple | Minimal error handler |
| errors-advanced | Rich error pages with stack traces |
#HTTP
| Package | Description |
|---|---|
| http | HTTP client contracts |
| http-guzzle | Guzzle HTTP driver |
#Filesystem
| Package | Description |
|---|---|
| filesystem | Filesystem contracts |
| filesystem-local | Local filesystem driver |
| filesystem-s3 | Amazon S3 driver |
#Encryption
| Package | Description |
|---|---|
| encryption | Encryption contracts |
| encryption-openssl | OpenSSL driver |
#Media
| Package | Description |
|---|---|
| media | Image processing contracts |
| media-gd | GD driver |
| media-imagick | ImageMagick driver |
#Pub/Sub & Real-Time
| 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 |
#Security & Access Control
| 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 |
| ratelimiter | Request rate limiting |
#Admin
| Package | Description |
|---|---|
| admin | Admin panel foundation |
| admin-auth | Admin authentication |
| admin-api | Admin REST API |
| admin-panel | Admin UI panel |
| admin-panel-latte | Latte templates for admin panel |
| admin-panel-twig | Twig templates for admin panel |
#Utilities
| 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 |
| devserver | Local development server |
| debugbar | Development debugbar and request profiler |
#Frontend & Build
| Package | Description |
|---|---|
| vite | Vite integration — asset manifest resolution and dev-server detection |
| inertia | Inertia.js protocol — middleware, response factory, shared data, SSR |
| inertia-react | React frontend marker binding for Inertia |
| inertia-svelte | Svelte frontend marker binding for Inertia |
| inertia-vue | Vue 3 frontend marker binding for Inertia |
#Documentation
| Package | Description |
|---|---|
| docs | Documentation search contracts |
| docs-markdown | Canonical Marko documentation content |
| docs-fts | FTS5 lexical search driver for documentation |
#AI-Assisted Development
| Package | Description |
|---|---|
| devai | AI tooling installer/orchestrator — wires MCP, LSP, and per-agent configs |
| mcp | Model Context Protocol server exposing Marko codebase introspection |
| lsp | Language Server Protocol implementation for Marko semantics |
| codeindexer | Shared static-analysis library backing the AI tooling |
| claude-plugins | Claude Code marketplace manifest and plugin assets |
#Testing
| Package | Description |
|---|---|
| testing | Test fakes, assertions, and Pest expectations |
#Example Applications
| App | Description |
|---|---|
| MarkoTalk | Real-time community chat — dogfoods plugins, preferences, events, SSE, and the admin panel |
#Requirements
- PHP 8.5+
- Composer 2.x
#Status
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.
#Contributing
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/phpcs
#Credits
Created by Mark Shust
#License
Marko is open-source software licensed under the MIT License.
