npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tsc_tech/medusa-plugin-woocommerce-migration

v0.0.2

Published

Complete WooCommerce to Medusa v2 migration plugin with streaming architecture, BullMQ-based checkpointing, and support for SQL dumps and CSV exports. Migrates products, orders, customers, taxonomy, and media with resume/pause capabilities.

Readme

@tsc_tech/medusa-plugin-woocommerce-migration

A Medusa v2 plugin to migrate WooCommerce data into Medusa. It migrates products, variants, and customers only. You upload WooCommerce CSV exports; the plugin uses a streaming architecture for large files and BullMQ for reliable, resumable jobs with pause/resume.


Compatibility

  • Medusa: >= 2.4.0 (Medusa v2)
  • Node: >= 20
  • Redis: Required (for BullMQ job queues)

Installation

1. Install the plugin in your Medusa app

From npm (when published):

yarn add @tsc_tech/medusa-plugin-woocommerce-migration
# or
npm install @tsc_tech/medusa-plugin-woocommerce-migration

From a local path (development):

yarn add /path/to/tsc_plugin_woocommerce-to-medusa-migration
# or with yalc
yalc add @tsc_tech/medusa-plugin-woocommerce-migration

2. Add the plugin to medusa-config.ts (or medusa-config.js)

Add the plugin to the plugins array and pass options. All configuration is provided by your Medusa app (via options and/or environment variables).

If using TypeScript (medusa-config.ts):

import path from "path";
import os from "os";

// Inside the plugins array:
{
  resolve: "@tsc_tech/medusa-plugin-woocommerce-migration",
  options: {
    // The URL of your Medusa backend server (used by workers to call the ingest webhook)
    backendUrl: process.env.MEDUSA_BACKEND_URL || "http://localhost:9000",
    // Default currency for imported product/variant prices (e.g. USD, INR, BRL)
    defaultCurrency: process.env.WOO_MIGRATION_DEFAULT_CURRENCY || "USD",
    // Default shipping profile ID for migrated items (optional; can be resolved from Fulfillment module)
    defaultShippingProfileId: process.env.WOO_MIGRATION_DEFAULT_SHIPPING_PROFILE_ID || "",
    // Connection string for your main database (used for project isolation / namespacing)
    databaseUrl: process.env.DATABASE_URL || "",

    config: {
      redis: {
        host: process.env.REDIS_HOST || "localhost",
        port: parseInt(process.env.REDIS_PORT || "6379", 10),
        password: process.env.REDIS_PASSWORD || undefined,
        db: parseInt(process.env.REDIS_DB || "0", 10),
      },
      upload: {
        // Temporary folder for uploaded files during migration.
        // Use system temp so the dev server file watcher does not restart when files are written (avoids "fetch failed" during ingest).
        tempDir: path.join(os.tmpdir(), "woo-migration"),
      },
    },
  },
},

If using JavaScript (medusa-config.js):

const path = require("path");
const os = require("os");

// Inside the plugins array:
{
  resolve: "@tsc_tech/medusa-plugin-woocommerce-migration",
  options: {
    backendUrl: process.env.MEDUSA_BACKEND_URL || "http://localhost:9000",
    defaultCurrency: process.env.WOO_MIGRATION_DEFAULT_CURRENCY || "USD",
    defaultShippingProfileId: process.env.WOO_MIGRATION_DEFAULT_SHIPPING_PROFILE_ID || "",
    databaseUrl: process.env.DATABASE_URL || "",

    config: {
      redis: {
        host: process.env.REDIS_HOST || "localhost",
        port: parseInt(process.env.REDIS_PORT || "6379", 10),
        password: process.env.REDIS_PASSWORD || undefined,
        db: parseInt(process.env.REDIS_DB || "0", 10),
      },
      upload: {
        tempDir: path.join(os.tmpdir(), "woo-migration"),
      },
    },
  },
},

3. Start your Medusa server

Ensure Redis is running, then:

yarn build
yarn dev
# or: npx medusa develop

The plugin registers an admin UI route and API endpoints automatically.


Configuration reference

| Option | Description | Default / Env | | -------------------------- | ----------------------------------------------------------------- | --------------------------------------------------- | | backendUrl | Medusa backend URL (used by workers to call the ingest webhook) | MEDUSA_BACKEND_URL or http://localhost:9000 | | defaultCurrency | Currency code for imported product/variant prices (e.g. USD, INR) | WOO_MIGRATION_DEFAULT_CURRENCY or USD | | defaultShippingProfileId | Default shipping profile ID for migrated items | WOO_MIGRATION_DEFAULT_SHIPPING_PROFILE_ID or "" | | databaseUrl | Main database connection string (used for project isolation) | DATABASE_URL or "" | | config.redis | Redis connection for BullMQ (host, port, password, db) | REDIS_* or localhost:6379 | | config.upload.tempDir | Directory for temporary uploads during migration | path.join(os.tmpdir(), "woo-migration") |

Important: Use a temp directory outside your project (e.g. path.join(os.tmpdir(), "woo-migration")) so the dev server file watcher does not restart when the plugin writes uploaded files. Using something like ./uploads/temp can cause the server to restart and the ingest step to fail with "fetch failed".


How it works

High-level flow

  1. Upload – You upload a WooCommerce CSV export from the Medusa Admin Woo Migrator page.
  2. Parse – A BullMQ worker reads the CSV in a streaming way and extracts raw records (products, variants, or customers).
  3. Transform – Another worker converts WooCommerce data into Medusa-shaped products, variants (with prices), or customers.
  4. Ingest – Workers send batches to the Medusa backend via the /hooks/migration-ingest webhook, which writes to the Medusa database (PostgreSQL) and creates store/region/price sets as needed for products.
Upload CSV → Parse (stream) → Transform (map to Medusa) → Ingest (HTTP → Medusa DB)

Progress, job state, and checkpointing are stored in Redis, so you can pause and resume migrations.

How to connect and use it

  1. Redis – Must be running and reachable at the host/port you set in config.redis. The plugin uses it for job queues and state.
  2. Medusa backend – Must be running at backendUrl. Workers call POST {backendUrl}/hooks/migration-ingest to persist data.
  3. Admin UI – After installing the plugin and starting the server, open your Medusa Admin and go to the Woo Migrator (or Migrations) section. From there you:
    • Choose entity type: Products, Variants, or Customers
    • For products/variants, optionally choose price currency for the migration
    • Upload your WooCommerce CSV file
    • Watch progress and use Pause / Resume / Cancel
    • View Failed and Skipped items per job when the migration finishes

What gets migrated

The plugin supports CSV only and completes migration for these three entity types:

  • Products – Simple and variable products; titles, descriptions, handles, status, categories, tags.
  • Variants – WooCommerce variations mapped to Medusa variants with options (e.g. Size, Color), SKU, and prices. Prices are stored in the currency you choose at upload; the ingest hook ensures a store and region for that currency so prices show in the Admin price grid.
  • Customers – WooCommerce customer exports mapped to Medusa customers.

Environment variables (in your Medusa app)

Set these in your Medusa app (e.g. .env); the plugin receives them only through the options you pass in medusa-config (as in the examples above).

| Variable | Purpose | | -------------------------------------------------------- | ------------------------------------------------------------- | | MEDUSA_BACKEND_URL | Backend URL for ingest webhook (e.g. http://localhost:9000) | | WOO_MIGRATION_DEFAULT_CURRENCY | Default currency for migration (e.g. USD, INR) | | WOO_MIGRATION_DEFAULT_SHIPPING_PROFILE_ID | Default shipping profile ID (optional) | | DATABASE_URL | Database URL (used for project isolation) | | REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB | Redis connection for BullMQ |


Admin UI

  • Route – The plugin adds a route in the Medusa Admin (e.g. Woo Migrator or Migrations).
  • Actions – Upload file, select entity type and currency, start migration, pause/resume/cancel, view job status and counts.
  • Post-migration – For each job you can open Failed items and Skipped items to inspect errors or duplicates.

Prerequisites

  • Node >= 20
  • Medusa v2 (e.g. >= 2.4.0)
  • Redis (for BullMQ)
  • PostgreSQL (your Medusa database)

Project files: what’s required vs optional

Plugin runtime needs only:

  • src/ – plugin source (built into .medusa/server when you run medusa plugin:build)
  • package.json – name, dependencies, exports

Safe to remove (plugin will still work):

  • Root .js filesanalyze_csv.js, essential_fields_analysis.js, verify_csv.js, test-csv-parse.js, test-csv-parsing.js, test-full-flow.js, test-project-identifier.js – used for local testing/analysis only; not imported by the plugin
  • scripts/compare-woo-medusa-counts.js, compare-woo-medusa-report.js, debug-options-flow.js – dev utilities; not used at runtime
  • All .md docsHOW_TO_IDENTIFY_VARIANTS.md, TESTING.md, PLUGIN_ARCHITECTURE.md, everything in docs/ (e.g. CSV_*.md, GUJARATI docs, medusa-variant-create-payload.json) – documentation only
  • Shell scriptsdeploy-plugin.sh, deploy-yalc.sh, deploy-force.sh, debug-images.sh – deploy/debug helpers
  • Data/reports – any .csv exports, compare-report.txt, csv-verification-report.txt, check-images.sql, wp-product-json – sample data or outputs
  • Config.yarnrc.yml, package-lock.json, .medusa-config/ – useful for dev/install but not required for the plugin to run in a Medusa app

Removing any of the “safe to remove” items will not break the plugin’s upload → parse → transform → ingest flow. Keep them if you want docs and dev tools; delete them if you want a minimal repo.


More documentation


License

MIT