/symfony-hexagonal-architecture
Symfony hexagonal architecture setup — project structure, module scaffolding, layer responsibilities, dependency rules. Triggers on: architecture, module, layer, hexagonal, scaffold, project structure, directory structure, new project, new module
$ npx -y skills add aligundogdu/symfony-hexagonal-skill --skill symfony-hexagonal-architecture --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/symfony-hexagonal-architecture
Context preview
The summary Claude sees to decide when to auto-load this skill.
Symfony hexagonal architecture setup — project structure, module scaffolding, layer responsibilities, dependency rules. Triggers on: architecture, module, layer, hexagonal, scaffold, project structure, directory structure, new project, new module
SKILL.md
symfony-hexagonal-architecture.SKILL.mddescription: "Symfony hexagonal architecture setup — project structure, module scaffolding, layer responsibilities, dependency rules. Triggers on: architecture, module, layer, hexagonal, scaffold, project structure, directory structure, new project, new module"
Symfony Hexagonal Architecture
You are an expert in Symfony hexagonal architecture (ports & adapters). Use this skill when users need to set up project structure, create new modules, or understand layer responsibilities.
When to Activate
- User wants to create a new Symfony project with hexagonal architecture
- User asks about project structure or directory layout
- User wants to scaffold a new module/bounded context
- User asks about layer responsibilities or dependency rules
- User mentions "hexagonal", "ports and adapters", "clean architecture" in Symfony context
Core Principles
Layer Direction (STRICT)
Presentation → Application → Domain ← Infrastructure
Infrastructure depends on Domain (implements ports), but Domain NEVER depends on Infrastructure.
Module Structure
Every module follows this structure under `src/`:
Domain/{Module}/
├── Entity/ # Aggregates and entities (pure PHP)
├── ValueObject/ # Immutable value objects
├── Event/ # Domain events (past-tense)
├── Exception/ # Domain-specific exceptions
└── Port/ # Interfaces for external dependencies
Application/{Module}/
├── Command/ # Write operations (final readonly)
├── Query/ # Read operations (final readonly)
├── DTO/ # Data transfer objects
└── EventHandler/ # Domain event handlers
Infrastructure/{Module}/
├── Persistence/ # Doctrine repositories, mappings
├── Messaging/ # Messenger handlers, transports
└── ExternalService/ # HTTP clients, third-party APIs
Presentation/{Module}/
├── API/ # REST controllers
├── CLI/ # Console commands
└── GraphQL/ # GraphQL resolvers/typesProgressive Refactoring (Existing Projects)
When working on an existing project that doesn't follow hexagonal architecture:
Step 1: Detect Current Structure
Before writing any code, check:
- Is src/ organized by layer (Domain/, Application/, etc.) or by traditional Symfony (Controller/, Entity/, Repository/)?
- Does the module the user is working on already follow hexagonal patterns?
- Are there Doctrine annotations directly on entities?
Step 2: Ask the User
When the user requests a feature/change in a non-hexagonal module, ALWAYS ask:
> "Bu modül (`{Module}`) şu anda hexagonal yapıda değil. Şu seçeneklerden birini tercih edebilirsiniz: > 1. **Önce refactor**: `{Module}` modülünü hexagonal mimariye taşıyıp, sonra yeni özelliği ekleyeyim > 2. **Sadece yeni kodu hexagonal yap**: Mevcut koda dokunmadan, yeni eklenen kısımları hexagonal yapıda oluşturayım > 3. **Mevcut yapıda devam et**: Bu sefer hexagonal yapıyı atlayalım > > Hangisini tercih edersiniz?"
Step 3: Incremental Migration (if user chooses refactor)
Migrate one layer at a time, in this order:
1. **Domain first**: Extract entities to `Domain/{Module}/Entity/`, create value objects, define port interfaces 2. **Application second**: Create Commands/Queries/Handlers, move business logic out of controllers/services 3. **Infrastructure third**: Move Doctrine repositories to `Infrastructure/{Module}/Persistence/`, extract mappings 4. **Presentation last**: Thin out controllers, add `ApiResponseTrait`, apply `#[IsGranted]`
After each layer, verify the code still works before moving to the next.
Key Principles
- **Never touch modules the user isn't working on** — only refactor what's in scope
- **One module at a time** — don't try to migrate the whole project
- **Keep the app working** — each step should be a working state
- **Respect user's pace** — some teams prefer gradual migration over months
Scaffolding a New Module
When user asks to create a new module, generate ALL directories and base files:
1. Create directory structure (all 4 layers) 2. Create a sample port interface in `Domain/{Module}/Port/` 3. Create a sample repository adapter in `Infrastructure/{Module}/Persistence/` 4. Bind the port to adapter in `services.yaml` 5. Suggest initial entities, commands, and queries based on the module purpose
Key Rules
1. **Domain purity**: No `use Symfony\...` or `use Doctrine\...` in any Domain file 2. **Port-first**: Define the interface before the implementation 3. **One module = one bounded context**: Modules communicate via events, not direct calls 4. **Namespace convention**: `App\Domain\{Module}\...`, `App\Application\{Module}\...`, etc.
References
See `references/` for detailed guides:
- `directory-structure.md` — Full directory layout with file examples
- `layer-responsibilities.md` — What belongs in each layer
- `dependency-rules.md` — Import rules and PHPStan enforcement
Read more
description: "Symfony hexagonal architecture setup — project structure, module scaffolding, layer responsibilities, dependency rules. Triggers on: architecture, module, layer, hexagonal, scaffold, project structure, directory structure, new project, new module"
Symfony Hexagonal Architecture
You are an expert in Symfony hexagonal architecture (ports & adapters). Use this skill when users need to set up project structure, create new modules, or understand layer responsibilities.
When to Activate
- User wants to create a new Symfony project with hexagonal architecture
- User asks about project structure or directory layout
- User wants to scaffold a new module/bounded context
- User asks about layer responsibilities or dependency rules
- User mentions "hexagonal", "ports and adapters", "clean architecture" in Symfony context
Core Principles
Layer Direction (STRICT)
Presentation → Application → Domain ← Infrastructure
Infrastructure depends on Domain (implements ports), but Domain NEVER depends on Infrastructure.
Module Structure
Every module follows this structure under `src/`:
Domain/{Module}/
├── Entity/ # Aggregates and entities (pure PHP)
├── ValueObject/ # Immutable value objects
├── Event/ # Domain events (past-tense)
├── Exception/ # Domain-specific exceptions
└── Port/ # Interfaces for external dependencies
Application/{Module}/
├── Command/ # Write operations (final readonly)
├── Query/ # Read operations (final readonly)
├── DTO/ # Data transfer objects
└── EventHandler/ # Domain event handlers
Infrastructure/{Module}/
├── Persistence/ # Doctrine repositories, mappings
├── Messaging/ # Messenger handlers, transports
└── ExternalService/ # HTTP clients, third-party APIs
Presentation/{Module}/
├── API/ # REST controllers
├── CLI/ # Console commands
└── GraphQL/ # GraphQL resolvers/typesProgressive Refactoring (Existing Projects)
When working on an existing project that doesn't follow hexagonal architecture:
Step 1: Detect Current Structure
Before writing any code, check:
- Is src/ organized by layer (Domain/, Application/, etc.) or by traditional Symfony (Controller/, Entity/, Repository/)? - Does the module the user is working on already follow hexagonal patterns? - Are there Doctrine annotations directly on entities?
Step 2: Ask the User
When the user requests a feature/change in a non-hexagonal module, ALWAYS ask:
> "Bu modül (`{Module}`) şu anda hexagonal yapıda değil. Şu seçeneklerden birini tercih edebilirsiniz: > 1. **Önce refactor**: `{Module}` modülünü hexagonal mimariye taşıyıp, sonra yeni özelliği ekleyeyim > 2. **Sadece yeni kodu hexagonal yap**: Mevcut koda dokunmadan, yeni eklenen kısımları hexagonal yapıda oluşturayım > 3. **Mevcut yapıda devam et**: Bu sefer hexagonal yapıyı atlayalım > > Hangisini tercih edersiniz?"
Step 3: Incremental Migration (if user chooses refactor)
Migrate one layer at a time, in this order:
1. **Domain first**: Extract entities to `Domain/{Module}/Entity/`, create value objects, define port interfaces 2. **Application second**: Create Commands/Queries/Handlers, move business logic out of controllers/services 3. **Infrastructure third**: Move Doctrine repositories to `Infrastructure/{Module}/Persistence/`, extract mappings 4. **Presentation last**: Thin out controllers, add `ApiResponseTrait`, apply `#[IsGranted]`
After each layer, verify the code still works before moving to the next.
Key Principles
- **Never touch modules the user isn't working on** — only refactor what's in scope
- **One module at a time** — don't try to migrate the whole project
- **Keep the app working** — each step should be a working state
- **Respect user's pace** — some teams prefer gradual migration over months
Scaffolding a New Module
When user asks to create a new module, generate ALL directories and base files:
1. Create directory structure (all 4 layers) 2. Create a sample port interface in `Domain/{Module}/Port/` 3. Create a sample repository adapter in `Infrastructure/{Module}/Persistence/` 4. Bind the port to adapter in `services.yaml` 5. Suggest initial entities, commands, and queries based on the module purpose
Key Rules
1. **Domain purity**: No `use Symfony\...` or `use Doctrine\...` in any Domain file 2. **Port-first**: Define the interface before the implementation 3. **One module = one bounded context**: Modules communicate via events, not direct calls 4. **Namespace convention**: `App\Domain\{Module}\...`, `App\Application\{Module}\...`, etc.
References
See `references/` for detailed guides:
- `directory-structure.md` — Full directory layout with file examples
- `layer-responsibilities.md` — What belongs in each layer
- `dependency-rules.md` — Import rules and PHPStan enforcement
A Claude Code plugin that enforces hexagonal architecture (ports & adapters) in Symfony projects. Works with both new projects (full scaffolding) and existing projects (progressive, module-by-module refactoring).
Other skills on symfony-hexagonal-skill.
- /symfony-api-response
Symfony API response standardization — JSON payload format, exception handling, controllers, REST endpoints, error responses, debug mode. Triggers on: API, endpoint, controller, response, error handling, JSON, REST, API response, exception subscriber, HTTP
Open skill - /symfony-cqrs-handlers
Symfony CQRS command/query handlers — commands, queries, handlers, bus configuration, use cases. Triggers on: command, query, handler, CQRS, bus, use case, command handler, query handler, message bus
Open skill - /symfony-doctrine-persistence
Symfony Doctrine persistence — repository adapters, entity mapping, migrations, transactions, database patterns. Triggers on: doctrine, repository, persistence, database, mapping, migration, ORM, entity manager, DBAL, transaction
Open skill - /symfony-domain-modeling
Symfony domain modeling — entities, value objects, domain events, aggregates, domain exceptions. Triggers on: entity, value object, domain event, aggregate, domain exception, domain model, domain logic, business rule, invariant
Open skill - /symfony-messenger-async
Symfony Messenger async processing — message queues, retry strategies, failure transport, Symfony Scheduler, idempotency patterns, background jobs. Triggers on: messenger, async, queue, retry, scheduler, background job, worker, transport, message queue, cron, scheduled task
Open skill - /symfony-ports-adapters
Symfony ports and adapters — port interfaces, adapter implementations, dependency injection, autowiring, repository interfaces. Triggers on: port, adapter, interface, repository interface, DI, autowiring, dependency injection, services.yaml, binding
Open skill

