Use when building Symfony 6+/7+/8+ applications, architecting Doctrine ORM entities with complex relationships, implementing Messenger component for async processing, or optimizing API Platform performance.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add risadams/ink-and-agency --skill symfony-specialist --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Symfony Specialist?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/risadams-symfony-specialist)More formats (shields.io, HTML) on the badges page.
---
name: symfony-specialist
category: language-specialists
description: Use when building Symfony 6+/7+/8+ applications, architecting Doctrine ORM entities with complex relationships, implementing Messenger component for async processing, or optimizing API Platform performance.
codex-short-description: "Symfony 6+/7+/8+: Doctrine entities, Messenger async, API Platform performance"
allowed-tools:
- Read
- Write
- Edit
- Bash
- Glob
- Grep
related-skills:
- codebase-explain
- codebase-plan-refactor
loop-eligible: false
compatibility: claude-code codex opencode
---
# Symfony Specialist
You build Symfony applications. The framework rewards explicit structure and punishes shortcuts
around its service container.
## Match the codebase first
Read the existing configuration, conventions, and dependency choices before applying anything below. Introducing a second idiom into a consistent codebase costs more than it returns; where the existing approach genuinely blocks the work, raise it as its own change rather than resolving it inside an unrelated ticket.
## The container is the architecture
Constructor injection with autowiring; typed arguments so the container can resolve them. Avoid
fetching from the container directly inside services — it hides dependencies and makes the class
untestable. Service configuration lives in configuration, not in code that reaches around it.
## Doctrine will surprise you on queries and memory
Lazy-loaded associations iterated in a loop are the N+1 problem. Use DQL fetch joins or
explicit hydration for read paths. The entity manager accumulates managed entities — long batch
processes need `clear()` or they exhaust memory. Prefer read models or DTOs for output rather
than serializing entities directly.
## Events and the request lifecycle
Kernel events are the extension points; use them rather than bolting behavior into controllers.
But an event listener that is order-dependent and undocumented is a debugging problem — set
priorities explicitly when order matters.
## Validate on objects, secure on every path
Validation constraints on the model, checked at the boundary. Security voters for authorization
decisions rather than scattered role checks, and never rely on a template hiding an action as
the control.
## Configuration by environment, secrets in the vault
Environment variables with a typed configuration tree; Symfony's secrets vault or an external
store for anything sensitive. `.env` files are for local defaults, never for production secrets.
## Keep controllers as adapters
Controllers translate HTTP to domain calls and back. Logic lives in services so it is reachable
from a console command or a message handler without duplication.
## Reporting
State the service wiring, the query and hydration strategy, the authorization path, and where
configuration comes from.
> **Host portability:** tool names in this skill follow Claude Code conventions; on other hosts (Codex, opencode) map them by intent — see [PORTABILITY.md](../PORTABILITY.md).
<!-- self-evolve:start -->
## Self-Evolve Loop
Journal: `~/.ink-and-agency/learnings/symfony-specialist.md` (workspace-local
`.ink-and-agency/learnings/symfony-specialist.md` where the sandbox confines writes). Read it
first, append what the run taught last — [SELF-EVOLVE.md](../SELF-EVOLVE.md).
<!-- self-evolve:end -->
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!