WooCommerce CSV Importer: Built-in Tool vs Plugins Compared (2026)
Compare WooCommerce CSV import options: the free built-in importer, WP All Import, WebToffee, and more. Includes column reference, variable products, and troubleshooting.

WooCommerce ships with a free built-in CSV importer. It landed in version 3.1, handles simple, variable, grouped, and external products, and doesn't need any plugins. For stores with straightforward catalogs, it just works. Really.
But if you're managing thousands of SKUs, subscription products, or need automated syncs on a schedule? You'll outgrow it fast. That's when you start looking at plugins or the REST API.
This guide covers the built-in tool, the best plugins with current pricing, the full CSV column reference, variable product imports (the part that trips everyone up), and the errors you'll probably hit along the way.
The Built-in WooCommerce CSV Importer
You already have this -- no installation needed. Go to Products > All Products and you'll see Import and Export buttons right next to "Add New."
How to Import Products
- Go to Products > All Products in your WordPress admin
- Click Import
- Choose your CSV file (or use the "Advanced Options" to specify a server file path)
- Map your CSV columns to WooCommerce fields
- Click Run the importer
The column mapper auto-matches common column names. If your headers don't match exactly, you map them manually. Not a big deal. Once you confirm, WooCommerce processes the file and shows a summary of what was created or updated.
Want to update existing products instead of creating new ones? Check the "Update existing products" option. WooCommerce matches on ID or SKU.
What the Built-in Importer Supports
| Product Type | Supported | How to Set It |
|---|---|---|
| Simple | Yes | Type = simple |
| Variable | Yes | Type = variable (requires two-step import) |
| Grouped | Yes | Uses Grouped products column with IDs or SKUs |
| External/Affiliate | Yes | Uses External URL and Button text columns |
| Virtual | Yes | Type = simple, virtual |
| Downloadable | Yes | Type = simple, downloadable |
CSV Format Requirements
Your CSV must be UTF-8 encoded. Sounds obvious, right? Then you export from Excel, which defaults to a different encoding, and suddenly all your special characters are garbled. WooCommerce's own docs say it plainly:
> "If possible, we recommend avoiding Microsoft Excel, as we've seen it have formatting and character encoding issues."
Google Sheets or LibreOffice are safer bets. Honestly, just avoid Excel for this.
| Requirement | Details |
|---|---|
| Encoding | UTF-8 |
| Boolean Values | 1 (true) or 0 (false) |
| Multiple Values | Comma-separated |
| Category Hierarchy | Use > separator (e.g., Clothing > T-Shirts) |
| File Types | CSV or TXT only |
| File Size | Server-dependent (PHP upload_max_filesize, typically 2-150 MB) |
To include literal commas in field values (like category names), escape them with a backslash: Places\, People\, Cities.
What the Built-in Importer Cannot Do
This is where you decide if you need a plugin.
| Limitation | Details |
|---|---|
| No image alt text | Cannot import alt text for product images |
| No draft export | Only exports published and privately published products |
| No scheduled imports | Manual process every time |
| No XML or Excel | CSV and TXT files only |
| No subscription products | Requires a plugin |
| Variable products | Needs a two-step import process |
| No JSON/serialized data | Custom meta must be plain text |
If you can live with these limits, save your money. The built-in tool does the basics well and it's free.
Complete CSV Column Reference
WooCommerce has a lot of columns. Like, a lot. You won't touch most of them for a typical import, but having the full reference beats guessing. The columns below match the official WooCommerce CSV schema.
Core Product Columns
| CSV Column | Maps To | Example | Notes |
|---|---|---|---|
ID | id | 100 | Overwrites data for that ID on import |
Type | type | simple, variable | Valid: simple, variable, grouped, external, variation, virtual, downloadable |
SKU | sku | TSHIRT-BLU-M | Required. Auto-generated if missing |
Name | name | Blue T-Shirt | Required |
Published | status | 1 | 1 = published, 0 = private, -1 = draft |
Is featured? | featured | 1 | Boolean |
Visibility in catalog | catalog_visibility | visible | Options: visible, catalog, search, hidden |
Short description | short_description | text | Plain text or HTML |
Description | description | text | Plain text or HTML |
Regular price | regular_price | 24.99 | Numeric only |
Sale price | sale_price | 19.99 | Numeric only |
Date sale price starts | date_on_sale_from | 2026-06-01 | Date or blank |
Date sale price ends | date_on_sale_to | 2026-06-30 | Date or blank |
Categories | category_ids | Clothing, Clothing > T-Shirts | CSV list; > for hierarchy |
Tags | tag_ids | summer, sale | CSV list |
Images | image_id / gallery_image_ids | URL | First = featured; comma-separated for gallery |
Inventory & Shipping Columns
| CSV Column | Maps To | Example | Notes |
|---|---|---|---|
In stock? | stock_status | 1 | Boolean |
Stock | stock_quantity | 50 | Numeric; parent for variations; blank = no management |
Low stock amount | low_stock_amount | 5 | Empty or number |
Backorders allowed? | backorders | 1 | 1, 0, or notify |
Sold individually? | sold_individually | 1 | Boolean |
Weight (unit) | weight | 200 | Numeric only |
Length (unit) | length | 30 | Numeric only |
Width (unit) | width | 20 | Numeric only |
Height (unit) | height | 10 | Numeric only |
Shipping class | shipping_class_id | bulky | Shipping class name |
Tax status | tax_status | taxable | taxable, shipping, none |
Tax class | tax_class | standard | Any existing tax class |
Attribute & Variation Columns
| CSV Column | Maps To | Example | Notes |
|---|---|---|---|
Attribute 1 name | attributes | Color | Global attribute or custom text |
Attribute 1 value(s) | attributes | Blue, Red, Green | Comma-separated; variations need 1 value per row |
Attribute 1 default | default_attributes | Blue | Default selection for variable products |
Attribute 1 visible | attributes | 1 | Boolean |
Attribute 1 global | attributes | 1 | 1 = uses global attribute taxonomy |
Parent | parent_id | id:100 or PARENT-SKU | For variations; links to parent product |
Linked Product & Downloadable Columns
| CSV Column | Maps To | Example | Notes |
|---|---|---|---|
Grouped products | children | id:100, id:101 | List of IDs or SKUs |
Upsells | upsell_ids | SKU-1, SKU-2 | List of IDs or SKUs |
Cross-sells | cross_sell_ids | SKU-1, SKU-2 | List of IDs or SKUs |
External URL | product_url | URL | For external/affiliate products |
Button text | button_text | Buy on Amazon | Custom buy button text |
Download 1 name | downloads | User Guide | Downloadable file label |
Download 1 URL | downloads | https://example.com/guide.pdf | Downloadable file URL |
Download limit | download_limit | 3 | n/a or number |
Download expiry days | download_expiry | 30 | n/a or number |
You can grab sample CSV data from the official WooCommerce repository to see how these columns work in practice.
How to Import Variable Products
Variable products are where things get annoying. The built-in importer needs a two-pass import -- it can't create a parent product and its variations in one go.
The Two-Pass Method
Pass 1: Create the parent variable product
Set up a CSV with the parent product row:
Type,SKU,Name,Attribute 1 name,Attribute 1 value(s),Attribute 1 visible,Attribute 1 global,Regular price
variable,TSHIRT,Basic T-Shirt,Size,"Small, Medium, Large",1,1,
Notice the parent row lists all attribute values but has no price. Prices go on the variations, not the parent. This trips people up constantly.
Import this file with "Update existing products" checked if the product already exists.
Pass 2: Import the variations
Create a second CSV with only variation rows:
Type,SKU,Name,Parent,Attribute 1 name,Attribute 1 value(s),Regular price,Stock
variation,TSHIRT-SM,Basic T-Shirt - Small,TSHIRT,Size,Small,19.99,50
variation,TSHIRT-MD,Basic T-Shirt - Medium,TSHIRT,Size,Medium,19.99,45
variation,TSHIRT-LG,Basic T-Shirt - Large,TSHIRT,Size,Large,24.99,30
Each variation row has Type set to variation, a unique SKU, and the Parent pointing to the parent product's SKU. One value per attribute -- not a list. Import this file without "Update existing products."
Why Two Passes?
The built-in importer processes rows one at a time, top to bottom. If variations show up before the parent product is fully created, the parent-child link breaks. The two-pass method sidesteps that.
Is this annoying? Yes. Plugins like WP All Import handle it in a single step, and if you're managing hundreds of variable products, that alone might justify the cost.
Image Import: What Works and What Doesn't
Images are URL-based. The first URL in the Images column becomes the featured image; additional URLs (comma-separated) become gallery images. Simple enough in theory.
| Feature | Details |
|---|---|
| External URLs | Supported; imported into Media Library |
| Redirect URLs | NOT supported (cloud storage redirect links fail) |
| Existing Media | Reference by filename if already uploaded |
| Alt Text | NOT supported via CSV import |
| Multiple Images | Comma-separated URLs; first = featured |
From the official documentation:
> "External URLs are supported and imported into the Media Library if used, provided the images are directly accessible and not behind a redirect script."
The no-alt-text limitation is genuinely frustrating if you care about SEO (and you should). You'll have to add alt text by hand after import, or pay for a plugin that supports it.
Plugin Comparison: Which One Do You Actually Need?
The built-in importer works for basic stuff. Once you need scheduled syncs, subscription products, or single-pass variable product imports, you're looking at plugins. Here are the main options with pricing I verified in February 2026 (though plugin prices change, so double-check before buying).
WP All Import
The most popular option -- 200,000+ active installs and 1,500+ five-star reviews. It does a lot.
WooCommerce-specific pricing:
| Plan | Price | What You Get |
|---|---|---|
| WooCommerce Import Package | $169/yr | Import Pro + WooCommerce Add-On |
| Professional | $299/yr | Everything: WooCommerce, ACF, JetEngine, Meta Box, scheduling |
| Unlimited Lifetime | $1,299 one-time | All current and future features forever |
The free version on WordPress.org handles basic CSV/XML imports for posts and pages. WooCommerce product imports? That's the paid tier.
What stands out: Drag-and-drop field mapping, handles files over 200MB, scheduled imports via cron, Google Sheets imports via URL, and Google Merchant Center exports. The 90-day money-back guarantee is generous.
WebToffee (Product Import Export for WooCommerce)
A good mid-range pick. 90,000+ downloads, 4.84/5 rating, and cheaper than WP All Import. Some features actually match or beat it.
| Plan | Price |
|---|---|
| Single Site | $69/yr |
| Up to 5 Sites | $129/yr |
| Up to 25 Sites | $249/yr |
What stands out: Supports CSV, XML, Excel, and TSV. Handles subscription products. Scheduled imports via FTP/SFTP. The bulk math formulas for price and stock updates are surprisingly useful -- you can do things like "increase all prices by 10%" in the import itself. 30-day money-back guarantee.
Product CSV Import Suite (Official WooCommerce Extension)
This is WooCommerce's own premium extension. You'd expect it to be the best option. It's not. At 2.8/5 stars from 12 reviews, it has a rough track record. Several reviews specifically call out problems with -- you guessed it -- variable product imports.
| Plan | Price |
|---|---|
| 1-Year | $59/yr |
| 2-Year | $94.40 (save 20%) |
What stands out: Relative stock adjustments ((+)10, (-)2), draft product exports (which the built-in tool can't do), and support for WooCommerce Bookings, Bundles, and Composites. HPOS compatible.
Feature Comparison Table
| Feature | Built-in (Free) | WP All Import ($169/yr) | WebToffee ($69/yr) | CSV Import Suite ($59/yr) |
|---|---|---|---|---|
| File Formats | CSV only | CSV, XML, Excel | CSV, XML, Excel, TSV | CSV only |
| Simple Products | Yes | Yes | Yes | Yes |
| Variable Products | Two-step | One-step | Yes | Yes |
| Subscription Products | No | Yes | Yes | Yes |
| Scheduled Imports | No | Yes (cron) | Yes (FTP/SFTP) | No |
| Image Alt Text | No | Yes | Yes | No |
| Column Mapping | Auto-match | Drag and drop | Interactive | Manual |
| Bulk Math Formulas | No | No | Yes | No |
| Export Draft Products | No | Yes | Yes | Yes |
| Max File Size | Server limit | 200MB+ | Server limit | Server limit |
| WooCommerce Orders | No | Yes | Separate plugin | No |
| Custom Fields (ACF) | Limited | Full support | Yes | Yes |
| Money-Back Guarantee | N/A | 90 days | 30 days | 30 days |
| Active Installs | Included in WC | 200,000+ | 90,000+ | 10,000+ |
My take: Under 500 simple products, one-time import? Use the built-in tool and don't spend a dime. Large catalog with regular updates? WP All Import at $169/yr is worth it. Tight budget and no need for order imports? WebToffee at $69/yr punches above its weight. I haven't tested every niche plugin out there, but I'd skip the official CSV Import Suite unless you specifically need Bookings or Bundles support -- the reviews are too rough to recommend it otherwise.
WooCommerce REST API and CLI
If you're a developer and CSV imports feel clunky, WooCommerce has a REST API (v3) and CLI commands too.
REST API
Create products with a POST request to /wp-json/wc/v3/products:
{
"name": "Premium Quality T-Shirt",
"type": "simple",
"regular_price": "21.99",
"description": "A comfortable cotton t-shirt.",
"categories": [{ "id": 9 }],
"images": [
{
"src": "https://example.com/tshirt.jpg",
"alt": "Premium T-Shirt"
}
]
}The batch endpoint (/wp-json/wc/v3/products/batch) processes up to 100 items per request with create, update, and delete arrays.
Authentication uses API keys from WooCommerce > Settings > Advanced > REST API. There are client libraries for PHP (automattic/woocommerce), Python (woocommerce), and Node.js (@woocommerce/woocommerce-rest-api). Pick your language.
WP-CLI Commands
WooCommerce has had CLI commands since version 3.0, under the wp wc namespace:
# List products
wp wc product list --user=admin
# Create a product
wp wc product create --name="New Product" --regular_price="29.99" --user=admin
# Update a product
wp wc product update 123 --sale_price="19.99" --user=adminCLI shines for very large imports where browser timeouts would kill the process. Write a shell script that reads your CSV and calls wp wc product create per row, or hit the REST API from whatever language you prefer. It's more work upfront but way more reliable at scale.
Common Errors and How to Fix Them
"Sorry, this file type is not permitted for security reasons"
Why: Your CSV has HTML content and WordPress gets suspicious about the file type.
Fix: Add this to wp-config.php temporarily:
define( 'ALLOW_UNFILTERED_UPLOADS', true );
Remove it right after the import. Seriously, don't leave this on. It's a security hole.
Alternative: Upload the CSV to /wp-content/uploads/ via FTP, then use the server file path in the importer's "Advanced Options."
File Size Exceeds Server Limit
Why: Your server's PHP upload_max_filesize is lower than your CSV file size. This is annoying and common on shared hosting.
Fix: Ask your hosting provider to bump the limit, or split your CSV into smaller files. For big files, upload via FTP and use the server path option instead.
Special Characters and Encoding Issues
Why: The CSV wasn't saved as UTF-8. Excel again.
Fix: In Excel, save as "CSV UTF-8 (Comma Delimited)" -- not just "CSV." Or better yet, use Google Sheets.
SKU Already Exists
Why: A product with that SKU already exists and you're creating instead of updating.
Fix: Check "Update existing products" during import. Done.
Variable Products Not Importing Correctly
Why: You're importing parent products and variations in the same pass.
Fix: Two-pass method. Parent first, variations second. The Parent column in the variation CSV should point to the parent SKU. See the section above for the exact format.
Images Not Importing
Why: Image URLs are behind redirects or aren't publicly accessible.
Fix: Use direct URLs. Cloud storage links with redirect scripts won't work -- this gets a lot of people. If images are already in your Media Library, reference them by filename instead.
Import Timeout or Memory Exhaustion
Why: Large CSV files blow past PHP execution time or memory limits. This gets messy with files over a few thousand rows.
Fix: Split into batches of 100-500 products. Bump PHP memory_limit to at least 256 MB and max_execution_time to 300 seconds or more. And import images separately from product data -- image downloads are what really slows things down.
Performance Tips for Large Imports
Importing thousands of products? These settings and habits make a real difference:
- Split files into batches of 100-500 products. Keep variable product families together in the same batch.
- Increase PHP limits before importing:
upload_max_filesize: 64 MB minimumpost_max_size: 64 MB minimummemory_limit: 256 MB minimummax_execution_time: 300 seconds minimum
- Import images separately from product data. Image downloads are the slowest part.
- Upload via FTP and use the server file path instead of browser upload for files over 10 MB.
- Disable unnecessary plugins during import to free server resources.
- Run imports during off-peak hours so your store doesn't slow down for customers.
- Back up your database before every import. Every single time. I'm not being dramatic -- one bad import can wreck your catalog.
- Use WP-CLI for catalogs over 5,000 products. Browser timeouts just aren't worth fighting.
A Simpler Approach with ImportCSV
Every method above puts the burden on you to nail the CSV format before uploading. One wrong column name, one encoding issue, one bad attribute value -- and the import fails. Sometimes silently, leaving you with half-created products in a broken state.
ImportCSV takes a different approach. Upload your CSV in whatever format you have, map columns visually with drag-and-drop, preview and fix errors before anything touches WooCommerce, then push clean data to your store. No file size limits. No PHP memory headaches. And if one row has a problem, it doesn't torpedo the whole import.
It works with WooCommerce, Shopify, Supabase, custom APIs -- pretty much anything. If you're a developer, there's an embeddable React component you can drop into custom WooCommerce admin panels.
Try ImportCSV free -- let it handle the validation and mapping while you focus on actually running your store.
Wrap-up
CSV imports shouldn't slow you down. ImportCSV aims to expand into your workflow — whether you're building data import flows, handling customer uploads, or processing large datasets.
If that sounds like the kind of tooling you want to use, try ImportCSV .