Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Installing Turbo

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Wouldn't it be cool if when we click on a link or even submit a form, instead of that triggering a full page reload, it made an Ajax call... then updated the page with the new HTML? Well, that's exactly what Turbo Drive does. And it's a huge step towards making our app feel like a single page application.

Turbo itself is... just a JavaScript library! It has nothing to do with Symfony. But Symfony does have a package that makes it easier to use. Let's go get that package installed.

Head back to your terminal, open a new tab and run:

composer require "symfony/ux-turbo:^1.3"

After this finishes... run: git status to see what its recipe did:

git status

Ok: it looks like it installed a new bundle... called TurboBundle. It also changed our package.json file... let's go find that. It added two new packages including turbo itself. The recipe also updated our controllers.json file, which we learned about in the Stimulus tutorial. This adds a new Stimulus controller to our app. More on what that controller does a bit later.

"controllers": {
"@symfony/ux-chartjs": {
"chart": {
"enabled": true,
"fetch": "lazy"
"@symfony/ux-turbo": {
"turbo-core": {
"enabled": true,
"fetch": "eager"
"entrypoints": []

But... you probably noticed that we have an error from yarn:

The file @symfony/ux-turbo/package.json could not be found. Try running yarn install --force.

That makes sense! As we learned about in the first tutorial, we need to re-install our yarn dependencies so it can copy the new @symfony/ux-turbo package from our vendor/ sdirectory into the node_modules/ directory. Let's do it:

yarn install --force

When that finishes... run yarn watch again and... it's happy!

yarn watch

Hello Turbo Drive

Cool! So the @hotwired/turbo JavaScript package is now installed. Now... what do we need to do to activate Turbo Drive?

The answer is... nothing! It's already working!

Head back to your browser and refresh the page. Start clicking around. Woh! It's alive! And it feels fast!

Open up your browser tools... and then go to network tools and watch for XHR requests - or Ajax request. Yep! Every single click is now an Ajax request. There are zero full page reloads!

We now have... dare I say... a single page app! Tutorial finished! Good luck!

Okay, okay... of course the tutorial isn't finished yet. Turbo Drive feels like black magic... and that's never a great feeling. So next, let's discover how Turbo Drive works behind the scenes. We'll also see how Turbo was magically activated simply by installing it and I'll introduce you to a few subtle features of Turbo Drive that are already making the experience feel extra quick.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=7.4.0",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "", //
        "doctrine/annotations": "^1.0", // 1.13.1
        "doctrine/doctrine-bundle": "^2.2", // 2.3.2
        "doctrine/orm": "^2.8", // 2.9.1
        "phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
        "sensio/framework-extra-bundle": "^6.1", // v6.1.4
        "symfony/asset": "5.3.*", // v5.3.0-RC1
        "symfony/console": "5.3.*", // v5.3.0-RC1
        "symfony/dotenv": "5.3.*", // v5.3.0-RC1
        "symfony/flex": "^1.3.1", // v1.18.5
        "symfony/form": "5.3.*", // v5.3.0-RC1
        "symfony/framework-bundle": "5.3.*", // v5.3.0-RC1
        "symfony/property-access": "5.3.*", // v5.3.0-RC1
        "symfony/property-info": "5.3.*", // v5.3.0-RC1
        "symfony/proxy-manager-bridge": "5.3.*", // v5.3.0-RC1
        "symfony/runtime": "5.3.*", // v5.3.0-RC1
        "symfony/security-bundle": "5.3.*", // v5.3.0-RC1
        "symfony/serializer": "5.3.*", // v5.3.0-RC1
        "symfony/twig-bundle": "5.3.*", // v5.3.0-RC1
        "symfony/ux-chartjs": "^1.1", // v1.3.0
        "symfony/ux-turbo": "^1.3", // v1.3.0
        "symfony/ux-turbo-mercure": "^1.3", // v1.3.0
        "symfony/validator": "5.3.*", // v5.3.0-RC1
        "symfony/webpack-encore-bundle": "^1.9", // v1.11.2
        "symfony/yaml": "5.3.*", // v5.3.0-RC1
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.1
        "twig/intl-extra": "^3.2", // v3.3.0
        "twig/string-extra": "^3.3", // v3.3.1
        "twig/twig": "^2.12|^3.0" // v3.3.2
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.0
        "symfony/debug-bundle": "^5.2", // v5.3.0-RC1
        "symfony/maker-bundle": "^1.27", // v1.31.1
        "symfony/monolog-bundle": "^3.0", // v3.7.0
        "symfony/stopwatch": "^5.2", // v5.3.0-RC1
        "symfony/var-dumper": "^5.2", // v5.3.0-RC1
        "symfony/web-profiler-bundle": "^5.2", // v5.3.0-RC1
        "zenstruck/foundry": "^1.10" // v1.10.0