BC Promise Demystified

Robin Chalas

Core Team

Quick Reminders



What about Symfony?

Meet the Symfony

BC Promise!

The Promise

  • Extends SemVer

  • Guarantees smooth upgrades

  • Enforced by the Core Team

  • Applied by Contributors

  • Serves users (and business!)

Let's go through it all.

Using Symfony Traits

Using Symfony Interfaces

So, Symfony

does not ever change


Of course, it does.

Interfaces CAN change

in a smooth way!

  • New methods can be virtually introduced.
  • Existing Methods can be deprecated.
  • A whole interface can be deprecated.

Deprecated method



Deprecated interface

Interfaces can change

  • PHPDoc + silenced deprecation notices
  • Proper upgrade path (i.e. immediate alternative)

But only with:

Still there:

Keeps working.

You've got time

Breaking changes only happen in the next major.

If you get a deprecation notice, just migrate your code when you can.


A set of deprecations is often fixed with a single action on your side (e.g. setting a config option).


If you struggle to fix one, take a look at UPGRADE files. 

Using Symfony Classes

It's covered 😉

Protip: Don't use Symfony Classes

Use interfaces instead.

No interface?

Probably not the service you are looking for.

Extending Symfony Classes

Protip: Don't extend

Symfony classes

Inheritance leads to tight coupling

And friction at time to upgrade.

Just a time-consuming round trip that could have been avoided.

Use composition instead.

Decorate the services you want to extend the capabilities.

The improvable

The better

No interface?

Again, probably not the extension point you are looking for.

No better service?

Did you look hard enough?

Maybe listen to an Event instead.

Still not?

Symfony dispatches

a ton of Events

Exceptions to the rule

Some helper classes are fine to use in your Infrastructural code (non business logic, think controllers).
E.g. The Security helper.

In your services, consider using low-level abstractions over classes.


  • @internal:
    Never, ever use it.
  • @final:
    Never, ever extend it.
  • @experimental:
    Use it with caution, it is meant for early feedback, it is likely to create friction at upgrade time, but you will have all our gratitude.

Traits ✅ Interfaces ✅

Classes ✅

What about services?

Using Symfony Services

  • Reference a service from another.
  • Decorate a service.
  • Extend a service.
  • Replace a service (carefully).

We guarantee BC if you:


Services whose name start with a dot are internal, don't use those.

It's safe overall 🙃

Mistakes happen

We are humans, we do mistakes.


We don't break BC on purpose, but it can happen.

In that case, please consider opening an issue on the main Symfony GitHub repository so we can discuss about it and try to fix our mistake.

Thank you 💚

Symfony BC Promise Demystifed

By Robin Chalas

Symfony BC Promise Demystifed

Everyone using Symfony needs to customize a built-in feature at some point, either to fit some specific business requirements or just to perform some extra tasks. Sometimes, that requires to change the way some core services are wired, which often leads to friction at time to upgrade. Should you just copy/paste the feature code and change it to your needs then? Fortunately, no. Most Symfony features are designed in a way that makes it possible to extend them somehow, with little or no tight coupling. In this talk, we will review the factors that should be taken into account in order to use and extend Symfony's code the right way, based on real-word examples and a deep dive into the backward-compatibility promise, plus some tips pulled out of my maintainer hat.

  • 1,754