Magento Open Source vs Adobe Commerce: Developer Differences
Magento Open Source and Adobe Commerce share most of their code. Same framework, same module structure, same checkout, same APIs. Adobe Commerce adds a set of commercial modules on top, plus access to Adobe's cloud infrastructure and SaaS services. For merchants the question is usually about features and license cost. For developers the question is different: what changes in the codebase, the database and the workflow, and what breaks if code written for one edition runs on the other.
This article sticks to those developer facing differences on 2.4.x. License terms and pricing change and are not covered here.
How the editions are packaged
Both editions install with Composer from repo.magento.com. Open Source uses the magento/product-community-edition metapackage. Adobe Commerce uses magento/product-enterprise-edition, which pulls in the Open Source packages plus the commercial modules. Your access keys decide which packages you can download.
composer create-project --repository-url=https://repo.magento.com/ \
magento/project-enterprise-edition=2.4.8 commerce
composer create-project --repository-url=https://repo.magento.com/ \
magento/project-community-edition=2.4.8 opensource
Moving from Open Source to Adobe Commerce is an upgrade in place: change the metapackage, run Composer and setup:upgrade. Moving back is much harder, because Commerce modules change the database schema, as explained below.
Features that exist only in Adobe Commerce
The commercial modules cover merchandising, marketing and operations features. The ones developers run into most often:
- Content staging and preview. Scheduled changes to products, categories, CMS content, price rules and cart rules, with preview of the store at a future date.
- B2B suite. Company accounts, shared catalogs, negotiable quotes, purchase orders, quick order and requisition lists, through a separate extension package. See Adobe Commerce B2B features.
- Customer segments and targeted content based on them.
- Related product rules that fill related, up sell and cross sell lists automatically.
- Gift cards, reward points and store credit.
- Returns (RMA) management.
- Catalog permissions to hide categories or prices by customer group.
- Private sales and events with invitations.
- Admin action logs and scheduled import and export.
- Visual merchandiser for category product positions.
Page Builder used to be on this list, but it has been part of Open Source since 2.4.3. Adobe also offers SaaS services connected to Adobe Commerce, such as Live Search and Product Recommendations, which run outside the Magento application and are installed as extensions.
The biggest code difference: row_id and staging
Content staging needs to keep several versions of the same entity, one per scheduled update. To do that, Adobe Commerce changes the primary key structure of staged entities. Tables such as catalog_product_entity, catalog_category_entity, cms_page, cms_block, salesrule and catalogrule get a row_id column, plus created_in and updated_in columns that define which version is active when. The EAV value tables for products and categories link to row_id, not to entity_id.
On Open Source, value tables link to entity_id. On Adobe Commerce, the same query returns nothing or the wrong version. This is the most common reason a third party extension works on Open Source and fails on Commerce. Any raw SQL that touches these tables must ask Magento which column to use:
<?php
declare(strict_types=1);
namespace Vendor\Catalog\Model\ResourceModel;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\EntityManager\MetadataPool;
class ProductValueReader
{
public function __construct(
private readonly ResourceConnection $resource,
private readonly MetadataPool $metadataPool
) {
}
public function getVarcharValue(int $productId, int $attributeId, int $storeId): ?string
{
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();
$connection = $this->resource->getConnection();
$select = $connection->select()
->from(['e' => $this->resource->getTableName('catalog_product_entity')], [])
->join(
['v' => $this->resource->getTableName('catalog_product_entity_varchar')],
"v.$linkField = e.$linkField",
['value']
)
->where('e.entity_id = ?', $productId)
->where('v.attribute_id = ?', $attributeId)
->where('v.store_id = ?', $storeId);
$value = $connection->fetchOne($select);
return $value === false ? null : (string) $value;
}
}
getLinkField() returns entity_id on Open Source and row_id on Adobe Commerce, so the same code runs on both. On Commerce, the catalog entity table also contains future versions of a product. The staging framework normally adds a filter on created_in and updated_in to collection queries, but a raw select like the one above may return a staged version. For anything beyond a quick lookup, prefer repositories and collections, which handle this for you.
Declarative schema files are also affected. A foreign key in your own table that references catalog_product_entity.entity_id is fine on both editions, because entity_id still exists. A foreign key to a value table needs to follow the link field. More on schema files in declarative schema and data patches.
Saving entities on Commerce
Because staged entities have versions, saving a product through a low level resource model can create inconsistent rows on Commerce. Use the service contracts, such as ProductRepositoryInterface, for writes. Scheduled updates are created through the staging APIs, not by setting dates on the product. Direct SQL updates to product tables, a shortcut some import scripts take, are risky on Commerce for the same reason. The service layer is explained in service contracts and repositories.
Cloud infrastructure
Adobe Commerce can run on Adobe Commerce on cloud infrastructure, a managed platform with its own way of working:
- Builds and deploys are driven by Git pushes and the
magento/ece-toolspackage. - Application and service configuration live in
.magento.app.yaml,.magento/services.yamland.magento/routes.yaml, and deploy behavior in.magento.env.yaml. - The filesystem is read only at runtime outside a few writable mounts, so anything that writes to code directories in production fails.
- Fastly is the CDN and full page cache, with its own module for VCL snippets.
Code that works on a self hosted server can fail there because it writes files in the wrong place or depends on a service that is not configured. Adobe Commerce can also be self hosted, in which case none of this applies.
Testing extensions on both editions
If you build modules for others, or a store might move between editions, test on both:
- Run integration tests against an Open Source and a Commerce installation. Differences show up in queries, fixtures and dependency declarations.
- Do not depend on Commerce modules in
composer.jsonormodule.xmlunless the module really needs them. Optional integrations can be split into a separate module that depends on the Commerce one. - Check plugins on classes that Commerce modules also plug into, such as price calculation, totals and customer group logic. Order of execution can change behavior.
- Search your code for
entity_idin joins with catalog, CMS or rule tables. Each one is a potential Commerce bug.
Static analysis helps here too. PHPStan with the Magento extension catches type issues, though not the row_id problem. See PHPStan for Magento 2.
Which one to build on
From a developer's view, Open Source is simpler: one ID per entity, no staging layer, fewer modules in the stack. Adobe Commerce makes sense when the business uses its features, especially staging, B2B or customer segments, and is ready to fund the work they need. Buying Commerce for one feature that a single extension could provide on Open Source is a common mistake. The opposite is also common: rebuilding B2B or staging on Open Source with several extensions that never fully work together.
FAQ
Is the code of Magento Open Source and Adobe Commerce the same?
The core framework and most modules are the same. Adobe Commerce adds commercial modules on top, and some of them, such as content staging, change the database structure of catalog and content tables.
Why does an extension work on Open Source but fail on Adobe Commerce?
The most common reason is raw SQL that joins EAV value tables on entity_id. On Adobe Commerce those tables link through row_id because of content staging. Use MetadataPool to get the link field.
Is Page Builder only in Adobe Commerce?
No. Page Builder has been part of Magento Open Source since 2.4.3.
Can I move from Adobe Commerce back to Open Source?
It is possible but not a simple package change. The row_id structure, staging data and Commerce only tables must be migrated or removed, so plan it as a migration project.
I am available for freelance Magento and Adobe Commerce work on either edition. If you need help with this, get in touch.
Related articles
Magento 2 Admin Security Hardening Checklist
Harden the Magento 2 admin: custom admin path, IP restriction, 2FA, lockout and session settings, user and role cleanup, API integrations and admin logs.
Magento 2 Admin Two Factor Authentication: Setup and Fixes
Set up Magento 2 admin two factor authentication: providers, forcing a provider, CLI commands to reset users, local development, API tokens and common problems.
Magento 2 Backup and Restore: What to Save and How
How to back up and restore a Magento 2 store: database dumps that import cleanly, media, env.php and the encryption key, offsite copies and tested restores.
Magento 2 Cart Price Rules: Add a Custom Condition
Add a custom condition to Magento 2 cart price rules: the combine event, a condition model with validate, promo rule attributes and performance traps to avoid.