DDD with Symfony. Without building it all yourself.
Symfony ships Doctrine, Messenger, and Dependency Injection. But no architecture for Bounded Contexts, no clear separation of Domain and Infrastructure, no generated DDD foundation. Jardis adds exactly that layer.
Symfony gives you tools. Not the architecture.
Doctrine is a solid Data Mapper. Messenger is a reliable bus. But DDD is more than tools. It is structure.
Doctrine Entities are not Domain Entities
Doctrine mapping annotations, lifecycle callbacks, and flush cycles permeate your entities. In practice, persistence logic blends with business rules. The domain layer becomes dependent on Doctrine, even though it should not be.
Weeks of boilerplate per Bounded Context
Commands, handlers, events, repositories, API contracts: all by hand. Every new Bounded Context means dozens of files that must be created, wired, and kept consistent manually. That costs weeks, not minutes.
Bounded Contexts only exist on the whiteboard
Symfony Bundles are not Bounded Contexts. In practice, entities, services, and repositories end up in the same src/ directory. Domain boundaries are folder conventions that nobody follows under time pressure. A service reaches into three domains, and nobody notices.
How Jardis brings DDD to Symfony projects.
Symfony stays responsible for HTTP, routing, DI, and messaging. Jardis generates the domain architecture that Symfony does not ship.
Dedicated Domain Entities alongside Doctrine
The builder generates 3-layer Entities as standalone PHP packages. Your domain logic lives separated from Doctrine mappings. Persistence becomes an infrastructure concern, and the domain stays clean. Doctrine remains as the persistence layer but no longer dictates your architecture.
Generated Commands, Queries, and Events instead of manual wiring
Jardis generates the complete CQRS infrastructure in PHP: Commands, Command Handlers, Queries, Query Handlers, and Domain Events. The output is compatible with Symfony Messenger, but the structure comes from the builder. No manual creation of handler classes for every use case.
Physical domain boundaries instead of folder conventions
Every Bounded Context becomes a standalone PHP package with its own dependency structure. The builder enforces isolation at the filesystem level. A service cannot accidentally reach into a foreign domain. This is architecture, not a guideline.
Why Symfony teams use Jardis for DDD.
Not because Symfony is wrong. But because DDD architecture demands more than Symfony ships.
Bounded Contexts as PHP Packages
Each domain becomes a standalone package with its own structure. Order, Payment, Compliance: physically separated instead of mixed in one src/ directory. Teams work independently.
Domain architecture in minutes instead of weeks
New Bounded Context? Define the schema, start the builder, generate production-ready code. No weeks of creating commands, handlers, events, and repositories by hand.
Every Bounded Context follows the same pattern
No debates about folder structure, naming, or layer separation. The builder generates consistent architecture. New developers find their way immediately because every domain is structured the same way.
Ready to bring DDD into your Symfony project?
Join the WaitlistFrequently Asked Questions
Answers to the most important questions about Jardis and Symfony in a DDD context.
No. Symfony stays responsible for HTTP, routing, dependency injection, security, and messaging. Jardis generates only the domain layer: PHP Entities, Aggregates, Commands, Queries, Domain Events, and the Repository Pipeline. These live as standalone packages next to Symfony's src/ directory.