DEV Community

Cover image for Plugin count is a terrible way to size a WooCommerce migration. Here's the data.
Mufatech
Mufatech

Posted on

Plugin count is a terrible way to size a WooCommerce migration. Here's the data.

Plugin count is the first number anyone quotes when sizing a WooCommerce to Shopify migration. "They're running 58 plugins, this is going to be a big one." Metorik's analysis of more than 6,000 stores says 58 is about average, so the number is real enough.

It is also close to useless, and we have the data to show why.

We mapped the 88 most common WooCommerce and WordPress plugins to whatever replaces them on Shopify, with a migration risk level on each one. Here is how they land:

What replaces it on Shopify Plugins Share
Built into Shopify 37 42%
Third-party app 19 22%
App made by Shopify 17 19%
Not needed at all 8 9%
Shopify Plus, or an app 4 5%
No native equivalent 3 3%

Half the stack isn't work. It's deletion.

Whole categories collapse into a checkbox

The interesting part isn't the percentage, it's which plugins vanish. They go in clusters:

Payments — five plugins, one setting. Stripe, WooPayments, PayPal Checkout and PayPal Payments all reduce to Shopify Payments; Klarna rides on the same rails. A payments stack that took a developer a week to assemble and now needs quarterly maintenance becomes a screen in the admin.

SEO — four plugins, two fields. Yoast, Rank Math, All in One SEO and Redirection all reduce to a native SEO title, a meta description and a redirect table. The plugin that was arguably the most important thing on the site turns into two text inputs. (Getting the content of those fields across is a real job — the values live in post meta, not in the product export — but that's a data problem, not an architecture one.)

Page builders — three plugins, gone. Elementor, Elementor Pro, WPBakery. Shopify's theme editor covers the same ground with sections and blocks. This is the one that makes people flinch, and it's also the one where migrations quietly improve the site, because the shortcode soup doesn't come along.

Performance, security and infrastructure — eight plugins, nothing. WP Rocket, LiteSpeed Cache, W3 Total Cache, Autoptimize, Wordfence, reCAPTCHA for WooCommerce, Jetpack, Post Views Counter. Nothing replaces them, because the platform owns the layer they were patching. Eight licences, eight update cycles and eight sources of compatibility bugs simply stop existing.

Gift cards, brands, cookie banners, variation swatches, predictive search, currency switching, ACF field groups: same story, each one a field or a setting rather than a purchase. The instinct that "58 plugins means 58 apps to buy" is wrong by a wide margin, and it's the assumption most migration quotes — and most merchant panic — are built on.

The 13 that actually cost you

Risk splits 33 none, 22 low, 20 medium, 13 high. The high group is small, and it's always the same shapes:

  • Subscriptions and memberships — WooCommerce Subscriptions, WooCommerce Memberships
  • Multilingual — WPML, Polylang, TranslatePress, WooCommerce Multilingual
  • Marketplaces — Dokan, WC Vendors, WCFM
  • B2B — B2BKing, Wholesale Prices
  • Bookings and composite products — WooCommerce Bookings, Composite Products

Thirteen plugins out of 88 decide almost the entire budget. A store with 60 plugins and none of these is a routine migration. A store with 12 plugins and WooCommerce Subscriptions is not. Counting gets that exactly backwards.

Subscriptions is the worst of them, because the part that matters isn't in WooCommerce at all. A subscription is a contract in the database plus a payment token held by the gateway. Export the contract and you have a billing schedule that cannot charge anybody.

Shopify documents four processors whose saved payment methods can be attached to a migrated customer:

Gateway What transfers Identifier you need
Stripe Credit cards only Customer ID (cus_…)
Braintree Credit cards, Apple Pay Customer ID + payment method token
Authorize.net Customer profiles Profile ID + payment profile ID
PayPal Billing agreements Agreement ID (B-…), reference transactions approval required

Anything outside that table means every subscriber re-enters a card, and you will not get all of them back. On the WooCommerce side those identifiers sit in post meta — _stripe_customer_id, _paypal_subscription_id — as the official Subscriptions importer/exporter documents.

That belongs in a quote on day one, not in a discovery call in week six.

Putting it on the command line

wp plugin list --field=name | npx woocommerce-shopify-plugin-map
Enter fullscreen mode Exit fullscreen mode
HIGH    WooCommerce Subscriptions → Shopify Subscriptions (free, by Shopify) or Recharge
        Active subscriptions depend on stored payment tokens. They move only if your
        payment gateway supports token migration; plan this before anything else.
HIGH    WPML → Shopify Markets with Translate & Adapt
        Translations are imported per language; translated URLs and hreflang change structure.
MEDIUM  Product Bundles → Shopify Bundles (free, by Shopify)
        Fixed bundles map cleanly, mix-and-match needs an app.
LOW     Yoast SEO → Native SEO title and description fields
NONE    WP Rocket → Not needed: Shopify CDN and caching
UNKNOWN my-custom-plugin

Ignored: woocommerce
5 of 6 plugins mapped · highest risk: HIGH
2 high and 1 medium risk plugins decide most of the migration effort.
Enter fullscreen mode Exit fullscreen mode

Input is deliberately forgiving, because plugin lists arrive in whatever shape the site gives you. Slugs, folder paths and asset URLs all resolve to the same entry:

lookup('wordpress-seo')
lookup('/var/www/wp-content/plugins/wordpress-seo')
lookup('https://example.com/wp-content/plugins/wordpress-seo/js/dist/x.js?ver=22.0')
// all → Yoast SEO
Enter fullscreen mode Exit fullscreen mode

That third form is the one that earns its keep. When you have a URL and no server access, the plugins a storefront will admit to are the ones whose assets it loads — so a crawl of asset paths becomes a plugin list, and a plugin list becomes a plan.

ls wp-content/plugins | npx woocommerce-shopify-plugin-map
npx woocommerce-shopify-plugin-map --file plugins.txt --markdown
npx woocommerce-shopify-plugin-map --json | jq '.by_risk'
Enter fullscreen mode Exit fullscreen mode

--markdown writes a table you can paste into a proposal. The command exits 2 when anything high risk is present, so it can gate a checklist or a build step. WooCommerce itself and the WordPress defaults are ignored rather than reported as unknown, which keeps wp plugin list output clean.

There's a library too — TypeScript types, no dependencies:

import { assess } from 'woocommerce-shopify-plugin-map';

const report = assess(installedSlugs);
report.highestRisk; // 'high'
report.byRisk;      // { none: 1, low: 0, medium: 0, high: 2 }
report.unknown;     // slugs we have no entry for
report.known;       // entries, highest risk first
Enter fullscreen mode Exit fullscreen mode

The data is the actual artifact

The CLI is a thin wrapper around a JSON file, and the JSON file is the point. It ships as plugins.json, plugins.csv and a JSON Schema under CC BY 4.0. Each entry carries the Shopify equivalent, an equivalent type, a risk level, notes on what to plan for, and a link to a longer write-up where one exists.

https://raw.githubusercontent.com/mufa-tech/woocommerce-shopify-plugin-map/main/data/plugins.json
Enter fullscreen mode Exit fullscreen mode

Use it in your own tooling, your own estimates, your own checklists. The only condition is attribution.

Corrections are the contribution we want most. Shopify ships features constantly, and every release makes some row here a little less true — a plugin that needed a paid app last year may be a checkbox today. That decay is the real maintenance cost of a dataset like this one, and it's why it's public rather than sitting in our internal notes. If you find a stale row, or a plugin you keep running into that's missing, open an issue or a PR.

We maintain it at Mufatech Studio, where we build Shopify themes and move stores off WooCommerce. If you'd rather start from a URL than a plugin list, our readiness scanner reads a storefront's public data with no login, and the migration guides go deeper on redirects, SEO fields, the 3-option limit and the subscription problem above.

If you're sizing a migration right now and something in your stack isn't in the table, put it in the comments — that's usually where the interesting ones come from.

Top comments (0)