22 Jul 2026 · 2 min read
Magento 2 code best practices: write code that survives upgrades
How to write Magento 2 code that stays maintainable and upgrade-safe — prefer events over plugins, keep di.xml lean, never rewrite core, and use view models.
Magento 2 projects rot when extensions fight each other and upgrades become scary. Most of that pain is avoidable with a few coding disciplines. This post is the "how to write it right" companion to the performance checklist.
Prefer events over plugins
Reach for an event observer when you only need to react to something. Plugins are for changing inputs/return values. Events keep modules loosely coupled, so two features can both respond to sales_order_place_after without colliding.
Keep di.xml lean
Declare only what you use. Don't globally replace classes "just in case." A narrow plugin scoped to one method beats a sweeping type preference that surprises other modules.
Never rewrite core
No Preference for a core class unless absolutely necessary — and almost never necessary, because plugins + events cover most cases. A preference is a fork waiting to break on upgrade.
Use view models, not logic in templates
Inject a view model (a plain class via ViewModel/... in layout XML) instead of cramming PHP into .phtml. Templates stay presentational; logic becomes testable.
Respect the contracts
Depend on interfaces (Magento\Catalog\Api\ProductRepositoryInterface), not concrete classes. Interfaces are far more stable across versions than implementations.
Make extensions upgrade-safe
- Put configuration in
di.xml/events.xml, not in patched core files. - Declare composer constraints that match the Magento version range you support.
- Add a
composer.jsonwith a realrequireon themagento/frameworkversion.
Test the seams
Unit-test view models and services in isolation; integration-test the plugin/observer wiring. A small test suite is what makes an upgrade a routine bump instead of a fire. Running those tests against a consistent, production-shaped local stack — for example one brought up with Govard — keeps "green locally" honest.
What's next in this series
With performance and code quality covered, how do you actually verify a store is healthy? Next: a repeatable Magento 2 audit checklist.
Next in this series: The Magento 2 audit checklist —
/blog/magento2-audit-checklist