Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

20 years of Symfony, what's next?


20 years of Symfony, what's next?


20 years of Symfony, what's next?


Avatar for Fabien Potencier

Fabien Potencier

November 27, 2025
Tweet

More Decks by Fabien Potencier

Other Decks in Programming

Transcript

  1. A few months ago, Ryan Weaver passed away Ryan was

    a pillar of the Symfony community
  2. Ryan gave so many great talks at conferences Ryan had

    so much energy on stage Ryan had a passion for teaching and passing on knowledge
  3. In the early days, Ryan helped our community via a

    symfony1 blog. Quickly, Ryan became instrumental in the success of Symfony. From documentation to the developer experience Ryan changed Symfony forever Thank you
  4. Thank you Upsun You saved my live release First time

    in my life I restored from a backup!
  5. From fabpot/symfony sf_releaser prepare-release 8.0 | source git co -b

    release-$VERSION sf_releaser update-changelog sf_releaser update-version sf_releaser create-pr From symfony/symfony export SPLITSH_PROJECT=symfony sf_releaser prepare-release 8.0 | source sf_releaser tag ⏳ splitsh check:create "*/$GITBRANCH" --watch splitsh tag:sync --tag v$VERSION 🐢 splitsh check:create "*/$GITBRANCH" --watch --tags sf_releaser update-version --dev git push sf_releaser release Our To Do list
  6. From fabpot/symfony sf_releaser prepare-release 8.0 | source git co -b

    release-$VERSION sf_releaser update-changelog sf_releaser update-version sf_releaser create-pr From symfony/symfony export SPLITSH_PROJECT=symfony sf_releaser prepare-release 8.0 | source sf_releaser tag ⏳ splitsh check:create "*/$GITBRANCH" --watch splitsh tag:sync --tag v$VERSION 🐢 splitsh check:create "*/$GITBRANCH" --watch --tags sf_releaser update-version --dev git push sf_releaser release Our To Do list + Check the repo is not dirty + Checkout the branch + Sync code with upstream + Find the version to release + Set environment variables + Parse the Git logs, Update CHANGELOG-X-Y.md and commit + Update Kernel.php, and commit + Push the branch to Github + Create a pull request and merge it + Cleanup
  7. ...

  8. Symfony 2: 21 components Symfony 3: 11 new components -

    Asset, Debug, ExpressionLanguage, Filesystem, Intl, Ldap, OptionsResolver, PropertyAccess, PropertyInfo, Stopwatch, VarDumper Symfony 4: 6 new components - Cache, Dotenv, Inflector, Lock, WebLink, Workflow Symfony 5: 8 new components - ErrorHandler, HttpClient, Mailer, Messenger, Mime, Notifier, String, VarExporter Symfony 6: 5 new components - PasswordHasher, RateLimiter, Runtime, Semaphore, Uid Symfony 7: 6 new components - AssetMapper, Clock, HtmlSanitizer, RemoteEvent, Scheduler, Webhook Symfony 8: 5 new components - Emoji, JsonPath, JsonStreamer, ObjectMapper, TypeInfo 57 components and counting
  9. Bridges to the external world Symfony 5: 10 new bridges

    Symfony 6: 51 new bridges Symfony 7: 33 new bridges Symfony 8: 23 new bridges | Component | Bridge Count | |-------------|--------------| | Notifier | 81 | | Mailer | 20 | | Messenger | 5 | | Translation | 4 | | Lock | 1 | | Total | 111 |
  10. From fabpot/symfony 🔥 sf_releaser prepare-release 8.0 | source 🔥 git

    co -b release-$VERSION 🔥 sf_releaser update-changelog 🔥 sf_releaser update-version 🔥 sf_releaser create-pr From symfony/symfony export SPLITSH_PROJECT=symfony sf_releaser prepare-release 8.0 | source sf_releaser tag ⏳ splitsh check:create "*/$GITBRANCH" --watch splitsh tag:sync --tag v$VERSION 🐢 splitsh check:create "*/$GITBRANCH" --watch --tags sf_releaser update-version --dev git push sf_releaser release Our To Do list
  11. ▪ Several times a day ▪ Help with debugging problems

    ▪ Help me when I’m outside of my comfort zone ▪ Mostly using Claude Code and Cursor nowadays But I never keep much as I care deeply about code, its aesthetic and how it's organized LLMs for coding
  12. ▪ More recently, I’ve also used them to automate boring

    tasks ◦ Things that should be automated as no to little value ◦ I know exactly how they should be done ▪ But I want the generated code ◦ To be as deterministic as possible ◦ To feel like I’ve done it myself Boring tasks
  13. ▪ Deterministic, no need for an LLM? ◦ Coding standards

    ◦ Scaffolding for web controllers, CLI commands, … ▪ Non-deterministic, LLMs shine ◦ Updating existing code ◦ Generating code where possibilities are huge Boring tasks?
  14. ▪ Package the “logic” (prompt, context, …) as a specific

    “agent” ▪ Control the generated code precisely ▪ Little human interaction ▪ Little code review needed ▪ Reach almost 100% accuracy ▪ Make it cheap ▪ Avoid vendor lock-in Packaging recurring tasks
  15. From fabpot/symfony 🔥 sf_releaser prepare-release 8.0 | source 🔥 git

    co -b release-$VERSION 🔥 sf_releaser update-changelog 🔥 sf_releaser update-version 🔥 sf_releaser create-pr From symfony/symfony ⭐ export SPLITSH_PROJECT=symfony ⭐ sf_releaser prepare-release 8.0 | source ⭐ sf_releaser tag ⏳ splitsh check:create "*/$GITBRANCH" --watch splitsh tag:sync --tag v$VERSION 🐢 splitsh check:create "*/$GITBRANCH" --watch --tags sf_releaser update-version --dev git push sf_releaser release Our To Do list + Check that all package repositories are up-to-date with the mono-repository + Create tags for all packages Tag the same commit as the mono repo
  16. Upgrade code ▪ A new CLI command that updates code:

    Help removing deprecations and using new features ▪ Carefully build the context with deterministic data: ◦ Facts about the code base: PHP version, Symfony version, ... ◦ Relevant upgrade guides only (with before/after examples), written and optimized for LLMS ◦ Determine files that need to be updated ◦ ...
  17. # Add support for `help` in `Symfony\Component\Console\Attribute\AsCommand` For all PHP

    classes using the `AsCommand` PHP attribute, we must use the new `help` property instead of calling the `setHelp()` method in the `configure()` method. *Before* ```php #[AsCommand( name: 'app:add-user', description: 'Add a new user' )] class SomeCommand { protected function configure(): void { $this ->setHelp(<<<TXT The <info>%command.name%</info> command adds a new user with the username passed to it: <info>php %command.full_name% jane-doe</info> TXT); } } ```
  18. *After* ```php #[AsCommand( name: 'app:add-user', description: 'Add a new user',

    help: <<<TXT The <info>%command.name%</info> command adds a new user with the username passed to it: <info>php %command.full_name% jane-doe</info> // ... TXT, )] class SomeCommand { protected function configure(): void { $this ->setCommand('username', InputArgument::REQUIRED) ; } } ``` Remove the `configure()` method if it does not do anything anymore after the changes.
  19. ▪ A new version of Maker bundle using LLMs to

    better compose generated files and allow for updating existing ones more easily. ▪ We are already upgrading existing files (like Doctrine entities), but updating the default base template, which can diverge drastically from the default, is way more complicated. Maker Bundle
  20. ▪ An enhanced version of the recipes:update command that would

    automatically resolve conflicts when possible. ▪ It could also open the door to recipe composition (by assembling small snippets). Security configuration is a good example. recipes:update conflict resolver
  21. ▪ Expose logs exception, profiler information, container and routes data

    from cache ▪ Expose tools: give me all console command classes with their paths As a debugger
  22. ▪ LLMs = HTTP APIs Frontier models (OpenAI, Anthropic) or

    local ones (Ollama, vLLM), they all speak HTTP ▪ Symfony already solved this: Symfony HTTPClient powers 40+ Mailer/Notifier bridges. The same pattern works perfectly for LLMs ▪ Additional challenge: many LLM apps need streaming support Talking to AI? It's just HTTP Symfony HTTP Client component
  23. ▪ Great prompts need dynamic context: RAG results, user data,

    business rules ▪ Twig already solves this: filters, conditionals, inheritance for clean prompt assembly ▪ System prompts are just templates: version control, test, and iterate like any other code Build better prompts with Twig Twig
  24. ▪ Control complexity with predictable workflows. When LLMs handle complex

    workflows, outcomes become unpredictable. Use Symfony Workflow to: ◦ Define explicit states and transitions ◦ Set guardrails and business rules ◦ Let AI decide within boundaries you control ◦ Handle human-in-the-loop before proceeding to the next step Keep AI workflows deterministic Symfony Workflow component
  25. ▪ LLMs can plan, but smaller models not so much

    ▪ Split the work ▪ Increase attention, also output quality/accuracy ▪ Reduce hallucination Avoid too many tasks in a single prompt
  26. ▪ Define the task precisely to avoid implicit assumptions and

    ambiguity ▪ Optimize the context to be short and straight to the point Narrow down the task
  27. ▪ Optimize the size of the context by providing only

    what's needed for the task ▪ Improve model accuracy ▪ Decrease costs (less tokens) ▪ Improve performance (less tokens) ▪ Rule of thumb: a human should enjoy reading the context Optimize the context
  28. ▪ For structured output: Schema validation and semantic validation ▪

    For code: Lint and run tests ▪ Auto-correct in a loop when errors ▪ Use LLM as judge ▪ A human in the loop is still needed Help improve accuracy
  29. ▪ Expose specific project context: ◦ CLI commands: console list

    --format=json ◦ Container information: var/cache/dev/App_KernelDevDebugContainer.* ◦ Routes info: var/cache/dev/url_*.php ◦ ... ▪ Expose profiler info for a specific request like logs, exception messages, configuration, ... ▪ Help answer questions like "give me all command classes" (avoiding the use of grep in a loop by LLMs) Tools via console commands/API?
  30. ▪ CHANGELOG with better deprecation info (before, after, edge cases,

    ...), maybe split into many files ▪ Specialized guides that explain how to solve specific tasks (add authentication, ...) ▪ Great pull request descriptions Anything optimized for LLMs is great for human as well Better documentation
  31. From fabpot/symfony 🔥 sf_releaser prepare-release 8.0 | source 🔥 git

    co -b release-$VERSION 🔥 sf_releaser update-changelog 🔥 sf_releaser update-version 🔥 sf_releaser create-pr From symfony/symfony ⭐ export SPLITSH_PROJECT=symfony ⭐ sf_releaser prepare-release 8.0 | source ⭐ sf_releaser tag ⏳ 🎉 splitsh check:create "*/$GITBRANCH" --watch 🎉 splitsh tag:sync --tag v$VERSION 🐢 splitsh check:create "*/$GITBRANCH" --watch --tags sf_releaser update-version --dev git push sf_releaser release Our To Do list + Check that all subtrees are up-to-date + Check that tags are consistent + Update version back to dev + Commit + Create the Github Release + Publish the blog post on symfony.com + Post on social media + Send notifications by email