Aller au contenu
← Retour aux projets

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.

PHP 8.5+ License: MIT Active Development Latest Version Total Downloads


#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 before and after hooks. 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 ::class constants.
  • 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

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

#Mail

Package Description
mail 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

Package Description
log PSR-3 logging contracts
log-file File-based log driver

#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.

Nouvelle version disponible.