Symfony 4: New Hope

On November 30, 2017 new version of Symfony Framework has been released and it looks like core team followed the Star Wars numbering pattern, as 4th version is much better, leaving previous three behind as they look like ‘prequels’ now.

In this article, I will try to sum up all important changes made in Symfony 4, so if you are familiar with Symfony 3 and want to get known with new version — this article is for YOU!


Internally, Symfony 4.0 is “just” Symfony 3.4 with removed depracations.
But from outside there is a big leap forward. Most changes (from the installation process, directory structure through using bundles, to coding itself) were made to improve Developer Experience with the framework.
Such system like Symfony, which can be used to create web apps as easily as to build other frameworks on top of it, must be complicated. But, as Symfony proves in new version, this complexity may be ‘hidden’ from the developer eyes.

First of all, remember that Symfony 4 requires PHP 7.1.3 or higher (which is AWESOME news!), so make sure your environment is up-to-date!


tl;dr — composer create-project symfony/skeleton PROJECT_NAME

Symfony 4 leaves behind previous methods of installation, but I won’t say it’s revolution — if you follow closely Symfony development you could see how it has evolved to current way.
When Symfony 2 was released , it was simple zip download. Later, when Symfony has adopted composer, it has changed into: composer create-project symfony/symfony-standard-edition PROJECT_NAME. This command was a bit problematic:

  • standard edition package was HUGE and it took a while for composer to resolve all dependencies
  • new developers didn’t really knew what Standard Edition is, are there (and where) other editions
  • standard edition have built-in simple demo so if you would like to start new project, you had to remove some example files

In 2015, new Symfony Installer has been announced. It has fixed the problem with timing as it was downloading zip file instead of putting it to composer, It also fixed the problem with demo app , as it have built-in separatesymfony demo command for newcomers. However, it was still additional tool that was have to been install beforehand.

So, Symfony 4 introduced new way of installation with symfony/skeleton package:

composer create-project symfony/skeleton PROJECT_NAME

How that it’s different from symfony/symfony-standard-edition? It has, pretty much, nothing in it — it’s only composer.json file with 5 dependencies:

“symfony/console”: “⁴.1”, 
“symfony/flex”: “¹.0”,
“symfony/framework-bundle”: “⁴.1”,
“symfony/lts”: “⁴@dev”,
“symfony/yaml”: “⁴.1”

which results installing 21 packages:

Those packages are ONLY those you need to run the framework. That means:

  • no default ORM
  • no default template engine
  • no any other components not necessarily needed for every project like: form, security.

Why? Because composition is better than inheritance!. Not every project needs database, not every projects needs templates (e.g. APIs!). Because of that, default vendor is 70% smaller!

So yes! Symfony 4 IS microframework.

Psss! If you loved Symfony 3 microkernel — Symfony 4 uses is by default.

But I do need a template engine!

Yes, yes — we all love twig. Say no more:

$ composer require twig 

Aaaand you have twig ready to work with. You don’t need to configure anything (declaring paths, enabling bundles, etc.), all is done for you automagically by Symfony Flex — composer plugin for managing Symfony applications. And it’s not available only for twig but for every Symfony component or external bundle!

Symfony Flex

Fabien Potencier wrote in April:

Fun fact: Composer started as a conversation about how to generically install bundles/plugins/extensions for Symfony and phpBB.
WTF fact: Neither Symfony nor phpBB uses Composer as a way to install its bundles/plugins/extensions.

Yes, installation of extension was sometimes “problematic”. You had to follow (long) files: first register the Bundle in AppKernel class, add configuration to the (already huge) config.yml, run some commands, etc. Now it’s done for you by Symfony Flex.

How? Every bundle installation follows the “recipe” defined in Symfony Flex Recipies repositories:

Let’s take the recipe for popular EasyAdminBundle from Javier Eguiluz:

What this recipe does? It tells Flex to:

  • register bundle for all enviroments (“prod”, “dev”, “test”)
  • copy files from recipe to config directory (each bundle will get his OWN config yaml file!)
  • if someone will try to call composer require admin — it will install this specific bundle

Last point is really important. You can see above that there are two repositories with recipes: symfony/recipies and symfony/recipies-contrib. First is maintained by Symfony Core Team and holds only recipies for Symfony components and bundles ‘opinionated’ by them. So, if someone needs an extension that makes admin panel — in Symfony Core Team opinion he/she should install EasyAdminBundle. And that’s what’s aliases entry is for. This option is not available on symfony/recipies-contrib repository which is for community-driven recipies.

But what if bundle I want to use doesn’t have the recipe? No problem, Flex would still be able to register it automatically in bundles.php — you would, however, still need to configure it by yourself if that’s the case. And if so, you are welcomed to make a PR for the bundle on symfony/recipies-contrib so it could be automated in the future.

All recipies (official and contrib) are listed on official site:

Important packages

Here you can find list of symfony components that were previously part of default installation and now should be installed separately. 
Below you will find list of (in my opinion) most useful or important:

  • debug which install DebugBundle
  • profiler for Web Profiler Toolbar
  • log for MonologBundle
  • web-server if you like server:start and server:stop commands for built-in webserver
  • orm if you need Doctrine
  • twig for our favorite template engine
  • mailer for SwiftMailer

Project Structure

A lot has changed here too, but again — to simplify things. Most important changes (from 3.x) are :

  • no app/ directory anymore: config/ is now top level directory (with config/packages with bundle-specific settings files), AppKernel.php is moved to src/Kernel.php
  • bundles are not defined directly in Kernel file anymore but in separate config/bundles.php file
  • web/ directory is now public/
  • we say goodby to app.php and app_dev.php — this is now one standard index.php file and environment is set with environmental variable APP_ENV
  • (when installed) twig templates are not kept in app/Resources/views but in templates/

Bye bye AppBundle!

Yes! Symfony 4 does not have ANY bundles in src/anymore.
All files now lives just in src/ directory (and have App/ namespace by default). That have effect on two things:


In Symfony 2 and 3, SensioGeneratorBundle was installed by default, which introduced couple of helpful generator console commands.
In Symfony 4 this is now replaced (and extended) by MakerBundle. To install it just type:

$ composer require maker

And you would have access to following generators:

make:auth                Creates an empty Guard authenticator
make:command Creates a new console command class
make:controller Creates a new controller class
make:entity Creates a new Doctrine entity class
make:form Creates a new form class
make:functional-test Creates a new functional test class
make:serializer:encoder Creates a new serializer encoder class
make:subscriber Creates a new event subscriber class
make:twig-extension Creates a new Twig extension class
make:unit-test Creates a new unit test class
make:validator Creates a new validator and constraintclass
make:voter Creates a new security voter class


I hope I was able to prove that Symfony 4 is still the good ol’ framework but with new look and feel which makes developer life’s easier. And that you are now ready to start your new project on Symfony 4.
On last SymfonyCon HackDay attendees made more than 170 Pull Requests to bundles to make them compatible with newest version, so your favorites should be ready — if not, make PR today!

If you have questions or feedback (which I’d love to hear!), leave comment here or catch me on twitter (I don’t write much but I retweet awesome PHP stuff A LOT):