Skip to content

marko-php/marko

Repository files navigation

██      ██   ██████   ██████    ██   ██   ██████
████  ████  ██    ██  ██   ██   ██  ██   ██    ██
██ ████ ██  ████████  ██████    █████    ██    ██
██  ██  ██  ██    ██  ██   ██   ██  ██   ██    ██
██      ██  ██    ██  ██    ██  ██   ██   ██████

Enterprise-grade extensibility meets modern PHP.

Override anything. Intercept any method. Extend any module — all without touching vendor code.

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

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

Caching

Package Description
cache Cache contracts and manager
cache-array In-memory cache (testing)
cache-file Filesystem cache driver
cache-redis Redis cache driver

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

Package Description
view View contracts and template resolution
view-latte Latte template engine integration

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
rate-limiting Request rate limiting

Content & Admin

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

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
dev-server Local development server

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

Learn More

Visit marko.build for documentation and updates.

Credits

Created by Mark Shust

License

Marko is open-source software licensed under the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages