Why msi-core
Two inventory systems in one
Section titled “Two inventory systems in one”Upstream Multi-Source Inventory ships with a second inventory system underneath it. The Default Stock is not a stock at all:
inventory_stock_1is a MySQL view overcataloginventory_stock_status;- the MSI indexer skips stock 1 on purpose;
- the salability of composite products for that stock is computed by the legacy CatalogInventory indexer instead of the MSI ones.
Around fifty if ($stockId === $defaultStockId) branches across twenty modules keep the two worlds
apart, each with its own data path. That split is the root of a whole class of defects: a bug fixed
on one side of the if stays open on the other. It also forces every new feature to be written and
tested twice.
What msi-core does about it
Section titled “What msi-core does about it”msi-core removes the split. Stock 1 is indexed, configured, edited and deleted like a stock you
create yourself, the composite indexers cover it, and the cataloginventory_* tables are neither
read nor written by MSI. One code path instead of two means a defect can no longer be fixed on one
side and stay open on the other, and a new feature is written and tested once.
On top of that single code path, msi-core adds features upstream does not have:
- source-level reservations, which close the cross-stock oversell gap;
- salable quantity broken down by source in the product form and grid;
- an adjustment history that records every change to a source item;
- a storefront stock visualizer;
- detection of writes that still target the frozen legacy tables.
What it costs
Section titled “What it costs”msi-core is a schema upgrade, not a package swap. It adds a table, migrates data into it and stops
writing two core tables. The upgrade needs a maintenance window, has no downgrade path, and breaks
code that reads cataloginventory_stock_item or cataloginventory_stock_status with raw SQL.
Upgrade from Magento MSI describes the break and the migration in full.
msi-core or the drop-in package
Section titled “msi-core or the drop-in package”The same fork is distributed as two packages from two repositories.
| Package | Repository | Magento | PHP | Drop-in |
|---|---|---|---|---|
jeanmarcos/inventory:2.4.7.* |
jeanmarcos-dev/inventory |
2.4.7 | 8.1 – 8.3 | yes |
jeanmarcos/inventory:2.4.8.* |
jeanmarcos-dev/inventory |
2.4.8 | 8.2 – 8.4 | yes |
jeanmarcos/inventory:2.4.9.* |
jeanmarcos-dev/inventory |
2.4.9 | 8.3 – 8.5 | yes |
jeanmarcos/msi-core:^1.0 |
jeanmarcos-dev/msi-core |
2.4.9 | 8.3 – 8.5 | no |
Pick jeanmarcos/inventory if you want the
curated fixes and nothing else to change. Composer swaps the package, the module names and
namespaces stay identical, and no migration runs.
Pick msi-core if you want one inventory system instead of two, and can accept a schema migration
with downtime and a documented break for code that reads cataloginventory_* by raw SQL.
They are two repositories rather than two branches of one because Packagist serves every branch of a repository under a single package name: a second package identity needs a second repository. The codebase is shared.
How the package works
Section titled “How the package works”msi-core keeps the original Magento_Inventory* module names and Magento\Inventory* namespaces.
It uses Composer’s replace directive to provide the 73 open-source MSI modules that ship with
Magento, plus its own modules. The replace covers the mage-os/* packages as well as the
magento/* ones, which is what makes it install on Mage-OS without further configuration. Mage-OS
3.x tracks Magento 2.4.9.
The build pins magento/framework to its target line, so Composer only installs it on a matching
Magento version.
The two packages replace the same modules and therefore cannot coexist. msi-core declares an
explicit conflict on jeanmarcos/inventory, so Composer refuses a tree holding both rather than
producing a broken one.