Vortos
One of our own projects: an event-driven PHP framework for Domain-Driven Design and Clean Architecture. Independent packages, compile-time wiring, no runtime reflection. It has a site and documentation of its own. This page is the short version.
- Packages
- 45+ published
- Release
- v1.0 alpha
- Licence
- Open source
- Language
- PHP 8.2+
Full documentation, installation and the module reference live on the project’s own site.
Why it exists
Assembled stacks compile. They don’t stay understandable.
Most PHP applications that need CQRS, an event log and a real authorization model end up assembling them from five libraries that agree on nothing: how a handler is discovered, what a domain event is, where a transaction boundary sits. The result works, and is impossible to reason about a year later.
Vortos is the opinionated version of that assembly. It starts from Domain-Driven Design and Clean Architecture, treats events as the primary integration mechanism, and ships every capability as its own package, so nothing is installed that isn’t used.
It is v1.0 alpha. The API is stable enough that we run our own product on it and pin exact versions, but there has been no stable 1.0 release and we don’t claim one. If you are evaluating it for a system you will own for five years, that’s the number that should inform the decision.
Declaration
01A program that declares its own structure.
Handlers, routes, subscribers and scheduled work are declared with attributes and collected when the container is built. There is no registration file to forget, no runtime reflection cost, and a missing or ambiguous registration fails the build instead of silently doing nothing in production.
| Attribute | Declares |
|---|---|
| #[AsCommandHandler] | This class handles this command |
| #[AsQueryHandler] | This class answers this query |
| #[AsEventHandler] | This method reacts to this domain event |
| #[RegisterConsumer] | This class consumes from this stream |
| #[Route] | This method answers this HTTP request |
| #[RequiresPermission] | This endpoint needs this permission |
| #[RateLimit] | This endpoint is bounded at this rate |
| #[Scheduled] | This command runs on this cadence |
| #[AuditLog] | This action is written to the audit trail |
Modules
0241 modules. Install the ones you need.
Each is a separate Composer package with its own documentation. You can take messaging without billing, or audit without feature flags.
Core
The parts every application uses.
-
vortos/foundation
Runner, container auto-discovery, compile-time wiring.
-
vortos/http
Attribute routing, controllers, error handling.
-
vortos/domain
Aggregates, identities, domain events, value objects.
-
vortos/cqrs
Command and query buses with idempotency.
-
vortos/config
Typed configuration with per-environment layering.
-
vortos/logger
PSR-3 logging, human-readable in dev, JSON in production.
Data
Persistence, caching and search.
-
vortos/persistence
Repository contracts and the unit of work.
-
vortos/persistence-orm
Doctrine ORM write repositories.
-
vortos/persistence-dbal
Direct DBAL access for read paths.
-
vortos/cache
PSR-16 cache with tag-based invalidation.
-
vortos/migration
Versioned schema changes with an analyzer.
-
vortos/search
Full-text search over the read model.
Messaging
Getting events out of the process safely.
-
vortos/messaging
Event bus, outbox, retries, dead-letter queues.
-
vortos/scheduler
Cron-style scheduled commands with locking.
-
vortos/sse
Server-sent events for live interfaces.
-
vortos/push
Web push delivery.
Access
Who may do what, and proving it afterwards.
-
vortos/auth
JWT authentication, rate limiting, two-factor.
-
vortos/authorization
Policy-based permissions and role hierarchy.
-
vortos/security
CSRF, headers, input sanitisation.
-
vortos/audit
Append-only audit trail with signed export.
-
vortos/tenant
Multi-tenant scoping primitives.
-
vortos/secrets
Encrypted secret storage and rotation.
Operations
Knowing what production is doing.
-
vortos/observability
The wiring that ties logs, metrics and traces together.
-
vortos/metrics
Prometheus-compatible application metrics.
-
vortos/tracing
OpenTelemetry distributed tracing.
-
vortos/health
Liveness and readiness checks with dispositions.
-
vortos/alerts
Alert routing with inhibition rules.
-
vortos/backup
Scheduled backups with verification.
Delivery
Getting it to production, repeatably.
-
vortos/docker
Production Dockerfiles for FrankenPHP or PHP-FPM.
-
vortos/deploy
Declarative deployment targets.
-
vortos/pipeline
CI pipelines generated from configuration.
-
vortos/make
Scaffolding for handlers, entities and projections.
-
vortos/debug
Development profiler and inspector.
-
vortos/release
Versioning and changelog automation.
Integrations
The third parties most applications end up needing.
-
vortos/object-store
S3-compatible object storage with lifecycle rules.
-
vortos/aws-ses
Transactional email delivery.
-
vortos/payments
Gateway-agnostic payment primitives.
-
vortos/paddle
Subscription billing with a webhook inbox.
-
vortos/feature-flags
Runtime flags with targeting rules.
-
vortos/analytics
Product analytics with an allowlisted schema.
-
vortos/mcp
Model Context Protocol server for agent tooling.
Proof
03It carries a real workload, with a real bill attached.
Vortos isn’t a side project that gets attention on weekends. It is the substrate for Sqoura, our own product, which means every package is exercised against real users and every rough edge is found by us before anyone else finds it.
We publish it because open work is the cheapest way to be judged accurately. It is one project among several, and it is the one you can read line by line before deciding whether to trust the people who wrote it.
Start a project
Tell us what you are building.
Send the shape of the problem. A paragraph is plenty. You get back how we’d build it, what it would take, and what the first two weeks look like. It comes the same day, from the engineers who would do the work.