Advance Sylius implementation

We’re standing before a decision, which way we should develop our product based on Sylius.

Scope: We want to develop more than 100 e-commerce solutions (B2B and B2C), operate and manage them for the next few years (5+ or even more).

The mindset evolutions

We decide to use Sylius due to its extendibility and mainly for the open-source approach.
By default, Sylius is extendible by creating customization in the src directory within Sylius Standard.
The next option is to develop Sylius custom Plugin, whose main profit is reusability.
Unfortunately, we encountered a few drawbacks.

The main drawbacks are DX and maintainability. Imagine that you have developed 30 plugins after the first year, and now you create the new one, which adds support of price lists to the Sylius due to new customer requirements (or Sylius just release a new version with a required feature).

Now you have to update all 30 plugins according to new changes with the new price management to use them in upcoming projects and update already released 50 projects. That is a lot of work to be done. All the more if you consider that you are doing this in separate repositories.

Some already published Sylius plugins have compatibility issues - they were written for Sylius 1.2 and they are no more compatible with new releases, etc.

Solutions

  1. Use the plugin approach as it is recommended in Sylius documentation.
  2. Come with new/different solutions.

While the first one is pretty clear, let’s talk about the second one.

The Product

If there will be more than 100 e-commerce solutions, which must be easily managed and operated there should be a new product created, new Sylius Standard with extra features - let’s say AcmeStandard.
The codebase must be the same for all projects running on AcmeStandard. The only thing that could be different is the configurations (YAML, ENVs, etc.) and templates. Otherwise, in a small team of developers, it’s unsustainable in the future.

AcmeStandard architecture

All Sylius components and bundles should be extended by AcmeStandard, additional functionality should be created in the component/bundle approach (PriceLists, etc.) and the entities of the project should extend the AcmeStandard entities. In plugins, we will be using just specific interfaces or the Acme custom model one. That all together should cover situations when you need to modify the model in all project, behaviour and so on. In case, that you’ll need to create some customization specific for one client, you should write it in the project’s src directory. Ideally, there should be a minimum of changes, because all different behaviour should be configurable in the specific bundle, once it turns out, it is needed elsewhere.
The whole AcmeStandard product have to be tested via phpSpecs and Behat of course.

The next benefit is that you can develop AcmeStandard product with all plugins in components in one a monorepo. Which is less time consuming when changes are needed (early development, maintenance).

In case that we want to publish some of our plugins to the community, there should be a workaround if you’re on pure Sylius, or AcmeSylius.

Do you have any recommendation or tips? Have you already dealt with something like this?