Vortos

Getting Started

Install Vortos and create your first application in minutes.

Getting Started

Vortos is a modern PHP framework built for domain-driven, event-driven applications. It provides a complete infrastructure layer — HTTP, auth, authorization, messaging, persistence, caching, CQRS, and tracing — with zero magic and full compile-time safety.

Design Philosophy

Every feature in Vortos is designed to have zero reflection at runtime. Discovery happens at compile time. Runtime is O(1) map lookups. Your application is fast by default.

Requirements

RequirementVersion
PHP8.2 or higher
Composer2.x
Redis7.x (for rate limiting, sessions, tokens)
PostgreSQL14+ (recommended for persistence)

Installation

composer create-project vortos/vortos my-app --stability=alpha
cd my-app

After installation, Vortos runs the setup wizard. Choose Docker or local development:

php vortos setup

The default Docker profile configures FrankenPHP, PostgreSQL, MongoDB, Redis, Kafka, and the optional MCP server. The minimal profile uses local PHP with in-memory cache and messaging.

For non-interactive setup:

php vortos setup --profile=docker --no-interaction
php vortos setup --profile=minimal --no-interaction

Setup writes generated local values to .env, publishes module config stubs into config/, and publishes Docker files when a Docker profile is selected. Do not commit .env; commit .env.example as the template.

If MCP is selected, interactive setup can wire a supported AI client immediately. You can also run it later:

php bin/console vortos:mcp:install

Start the application with Docker:

php vortos up

Or run without Docker:

php -S 127.0.0.1:8000 -t public

Then check readiness:

curl http://localhost:8000/health/ready

Project Structure

my-app/
├── bin/
│   └── console              ← CLI entry point
├── bootstrap/
│   └── app.php              ← Application bootstrap
├── config/
│   ├── services.php         ← Service registration
│   ├── auth.php             ← JWT, lockout, session config
│   ├── authorization.php    ← Role hierarchy config
│   ├── cache.php            ← Cache adapter config
│   ├── messaging.php        ← Messaging driver config
│   ├── persistence.php      ← Database connection config
│   └── tracing.php          ← Tracing sampler config
├── public/
│   └── index.php            ← HTTP entry point
└── src/                     ← Your application code
    └── YourContext/
        ├── Domain/          ← Aggregates, events, value objects
        ├── Application/     ← Command handlers, query handlers
        └── Infrastructure/  ← Repositories, controllers

First Controller

src/User/Infrastructure/Http/UserController.php
use Vortos\Http\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Vortos\Http\Attribute\AsController;
use Vortos\Auth\Attribute\RequiresAuth;
use Vortos\Auth\Identity\CurrentUserProvider;

#[AsController]
#[Route('/users')]
#[RequiresAuth]
final class UserController
{
    public function __construct(
        private CurrentUserProvider $currentUser,
    ) {}

    #[Route('/me', methods: ['GET'])]
    public function me(): JsonResponse
    {
        $identity = $this->currentUser->get();

        return new JsonResponse([
            'id'    => $identity->id(),
            'roles' => $identity->roles(),
        ]);
    }
}

What's Next

On this page