Love it or hate it, Magento is today still one of the leading applications when it comes to open source e-commerce. Its ecosystem is huge, it’s flexibility overwhelming, its complexity staggering and therefore, its name is often referred to as the best or the worst you can encounter in the PHP world. However, instead of repeating what others are saying about Magento, let’s have an open look at what Magento has to offer - pointing out the good, the bad and the ugly parts.
Forget about Magento, I build the shop in Symfony!
Imagine that you are building a plain PHP application with Symfony. Awesome stuff, because you can determine all of its functionality yourself. Some third-party Symfony components are brought in via composer. But then the app needs to support a shopping cart. Alright, we can build that with a bit of JS and some generic modelling. Stripe is easily added as well, until that moment that the client realizes that the transaction fees of Stripe are higher than Adyen. And a year later, another payment provider. In the meantime, you are trying to remove the legacy by introducing a common payment gateway architecture. And what about gift cards and specific discounts for specific customer groups? If you think e-commerce is easy, think again. It is big business and the only way a merchant is able to survive is by adding new features to outrun the competitor. And if the merchant needs to pay for all your refactoring and all your rookie mistakes, the more you will realize that you would have been better off reusing some ready-made e-commerce framework than building things from scratch.
This doesn’t necessarily mean that you should use Magento. Close to Symfony, there are Sylius and Shopware. There are others like BigCommerce and Shopify. But if there are more and more features that need to be swapped out on a regular basis, the thing that you are looking for is less a greatly adjustable PHP framework, but more an ecosystem with a huge abundance of extensions. And that’s where Magento has always been popular: There are 1000s of extensions (some good, some bad), there are 1000s of developers, there are 1000s resources - the ecosystem is huge. And this usually means that solutions are found quicker. However, whenever an ecosystem grows, there are going to be bad apples in the basket as well. Let’s review those apples.
The bad - Insane complexity
There are reasons to like Magento and there are reasons to dislike Magento. In this writing, we’ll go through some of these reasons and try to prove the opposite. One of the reasons to call Magento trash, is that it is complex - very complex. It doesn’t try to be a lightweight cart, it tries to be an enterprise package, where flexibility leads to complexity. Without knowledge of Magento, you’ll have a hard time modifying Magento.
This is actually no different from any enterprise package out there (Magento competitors, but also CRMs, ERPs, PIMs). The same is actually true for Laravel and Symfony - you’ll first need to learn the basics, before it starts to make sense. It’s just that Laravel and Symfony offer the barebones minimum, while Magento offers a complete e-commerce system out-of-the-box. More functionality means more required knowledge before you even start.
That being said, Magento is sometimes overdoing things: It tries to be so much enterprise, that the word “over-engineering” comes to mind. The database architecture of EAV is one example here, where one SELECT query to fetch a single product requires 15 additional JOINs. Or another example is that current Magento versions include over 350 modules. Yet another example is that the DI container of Magento is insanely configurable.
True, things could be made more simple, but there is something to say for that more complex architecture as well. If you are looking for a turn-key shop with little functionality, use WooCommerce instead. But if you’re looking for more advanced features, Magento has a solution. It is just that you as a developer need to configure things first.
The ugly - Outdated code
One other thing that developers often hate about Magento is ugly code: 9 out of 10 times, this actually deals with third party extensions. In some projects, third party modules are reviewed thoroughly before being added to the project. But in some other projects, even the ugliest extensions are added without thinking, resulting in the nightmares that you as a boss try to steer away from. But that’s not Magento's fault: That’s the fault of those third party extensions. Or the fault of the community that is still supporting those extensions. Or the fault of the popularity of Magento that has caused it to be used for shops, that would have been better off by using WooCommerce or a custom Symfony build. In either case, don’t blame Magento right away.
Except for that 1 out of 10 times, Magento is actually responsible for that ugly code. The best example for this is the Product-model. But if you closely inspect that class, you’ll realize that it is marked as @api to make sure it is backwards compatible, while all the recommendations are to depend with your new code upon a clean ProductInterface and/or ProductRepositoryInterface. Don’t expect that all of the code in Magento is perfect. There is legacy as well. But if you stick to the best practices, your code will not touch upon the legacy and no harm is done.
The ugly - Obsolete libraries
One of the things that strikes with Magento (as a hybrid between framework and application), when comparing it to framework-only projects like Symfony, is its slow progress. When PHP 8 came out in November 2020, it took Symfony merely days to be compatible with it. Actually most components were made PHP8-compliant before the official release. Yet, with Magento, compatibility with PHP 8 is still work-in-progress. Currently, Magento has migrated all Zend Framework components (since Zend Framework is dead) to Laminas, but this took quite some time. The frontend of Magento is still using RequireJS, KnockoutJS and jQuery which are all regarded as outdated by any modern frontend developer. In short, Magento seems to be getting rid of obsolete libraries only at a really, really slow pace. That’s ugly.
But that ugly aspect of being addicted to outdated libraries is actually a story of most ready-made applications. While a framework has no issue with releasing a new major, breaking backwards compatibility, requiring developers to rewrite things, with a ready-made application this is much harder: There are much more dependencies, much more people are relying upon the out-of-the-box behaviour. And merchants are not happy to upgrade every month, requiring them to rewrite the code base. They want to invest first, then freeze the shops code to make money from it. Just upgrading any library in Magento is far too complex, because it will break yet other libraries and extensions. With Symfony, the ecosystem might be full of variety, but the end-product is pretty much skinned down. With Magento, the end-product is huge and full of features.
Perhaps you can call it almost a rule of thumb: Any application that offers out-of-the-box an abundance of features is relying upon more code. And therefore it requires more effort to upgrade that code without breaking code. Therefore it is a slower pace.
The good - plentiness out of the box
The fact that Magento offers so many features out-of-the-box is a definite plus, compared to other carts and surely also compared to framework-only projects. There are numerous Magento modules. Some of them lead to conflicts with other modules. But if you stick to the modules that are coded properly, that ship with the right tests and that are doing their best to avoid conflicts, then you can pretty much rely upon those modules to lower the overall costs.
Magento itself is also built in a modular way. The architecture for third party modules is also applied to the core. It’s just that the out-of-the-box application shoves unwanted bundled extensions and numerous core modules in your face, which means that there is not only plenty to use, but also plenty to troubleshoot. Less is more, so removing features again is one of the common pra\ctice of a good Magento developer. Disabling modules is step one, but there are also composer replacements, DI tricks. Magento is slowly going API-first as well, so you can even swap out the frontend for a Tailwind / Alpine variation like Hyva, or go completely headless with a React or Vue app connecting to the GraphQL API.
The plentiness of Magento should be considered an all-you-can-eat buffet: It does not mean that you actually should eat everything - that strategy leads to obesity, costs you your health and it makes you move slower. The same applies to Magento: The less features a shop has, the easier an end-user will experience navigating through it. The less extensions, the easier upgrades will be. And the less needless core features are in the way, the better the rest of the core can be appreciated. The responsibility lies with you as a Magento developer to steer through this wild sea to make sure the project ends up with the right mix of core features, third party extensions and custom code.
The good - Magento is a framework too
Most of the downsides of Magento could be related to the fact that Magento forms a ready-made application, which is quite different from framework-only tools like Symfony. But Magento is a framework too. It offers an API to developers, so that a shop could be based upon the existing frontend but you could equally create your own frontend instead. It offers an API so that you could hook into the core using various extension points (with tools like service contracts, constructor argument replacements, observable events, XML configurations and Virtual Types) and replace things that you would like to have working differently. Don’t like the frontend? Build your own. Don’t like the multi-source inventory system. Write preferences pointing to your own stock classes. Think the performance of the ProductRepository could be improved. Improve it with a preference or via method interception.
The enormous configurability offered by the Magento Admin Panel, the abundance of third party extensions, the promotion of out-of-the box features - it sometimes makes you think that Magento is about a non-technical administrator clicking a shop together, only to ask a developer to clean up the mess. But this is far from the actual truth: In real life, agencies let non-technical users only deal with non-technical tasks, while the architecture is determined by technical minds. Whether third party extensions are used or not is a personal choice you need to make. Whether you’re sticking to the core or swapping it out with your own custom work or libraries that are “Proudly Invented Elsewhere” (PIE), is something that comes with the job as a Magento developer.
Don’t treat Magento as just an application. It is a mix, a hybrid between an application and a framework. And the ratio between these two depends on your level of expertise.
Conclusion: Magento is there for a reason
Most long-living communities think their own project is the best there is. And with that, there will be outsiders that will simplify things by saying that project sucks. But if everything about Magento would really suck, if no professional developer would actually like it, if every project ever based on Magento would have been a nightmare, then Magento would never have been a success. And the opposite is true: Magento has been the market leader (in the market of open source e-commerce systems) for about a decade. It’s ok to be critical. Just realize that every downside could be smoothened, every upside could be criticized. Magento is there for a reason and those reasons will make sure that Magento is going to stick around for some time to come.