VERGE

VERGE

A minimal PHP framework for code that explains itself.

index.php
Verge::app()->group('/weather', function ($app) {
    $app->singleton(WeatherService::class, WeatherApi::class);
    $app->controller(WeatherController::class);
    $app->get('/health', fn () => 'Weather service is running');
})->run();

Built Different

Four principles that guide every design decision

Four Primitives. Infinite Possibilities.

Everything in Verge is built from these composable building blocks

Container

PSR-11 dependency injection with singleton, scoped, and transient bindings

$app->singleton(Cache::class)
Router

Fast route matching with parameters, groups, and named routes

$app->get('/users/{id}', ...)
Middleware

PSR-15 pipeline for auth, CORS, logging, and request transformation

$app->use(AuthMiddleware::class)
Events

PSR-14 dispatcher with wildcard listeners for decoupled hooks

$app->on('user.created', ...)

Driver-first design

The driver pattern is built into the framework. Swap service implementations via environment variables. Build your own driver-based services using the same pattern the framework uses for cache and logging.

use App\Queue\SyncQueue;
use App\Queue\RedisQueue;

app()
    ->driver('queue', 'sync', fn() => new SyncQueue())
    ->driver('queue', 'redis', fn(App $app) => new RedisQueue(
        $app->env('REDIS_URL')
    ))
    ->defaultDriver('queue', 'sync');

// Switch via QUEUE_DRIVER environment variable
$queue = app()->driver('queue');

Built-in event system

Listen to native framework events or dispatch your own. Hook into the request lifecycle, react to application events, and build event-driven features without external dependencies.

// Listen to native framework events
app()->listen('request.received', function(Request $req) {
    logger()->info('Request received', ['path' => $req->path()]);
});

// Dispatch and handle custom events
app()->listen('order.created', fn($order) => sendEmail($order));

app()->post('/orders', function(EventDispatcher $events) {
    $events->dispatch('order.created', ['id' => 123]);
    return ['status' => 'created'];
});