wp-cli/import-command
WP-CLI command for importing content into WordPress from WXR export files. Adds wp import, restoring the importer functionality removed from WP-CLI core. Automatically detects and runs the matching WordPress importer plugin, making site migrations and content restores scriptable.
What this package actually is. wp-cli/import-command is a WP-CLI command package, not a general-purpose PHP library. It registers wp import <file> --authors=<create|mapping.csv> and parses a WXR (WordPress eXtended RSS) export, writing posts, terms, comments, and authors into a live WordPress database via WordPress core APIs (wp_insert_post, wp_insert_term, wp_insert_attachment, etc.). It is a CLI surface over WordPress internals, not a reusable content-transform library with a versioned public API.
Architecture fit — low as a dependency, moderate as a tool. Nothing in its execution path is Laravel-aware. It bootstraps the WP-CLI runtime, expects a WordPress installation root (wp-config.php, $wpdb, plugin/theme context), and depends on WordPress core functions that have no analogue in Illuminate. composer require inside a Laravel project will install the code, but the code cannot meaningfully execute without a WordPress runtime. The only architecturally sound role for it in a Laravel estate is as an out-of-band migration utility — a stage in a WordPress-to-Laravel content cutover, run in a disposable container, producing data that a native Laravel importer then consumes.
Integration feasibility — feasible, but only across a process boundary. The viable pattern is: run wp import against a scratch WordPress instance in a sidecar/one-shot container, then read from that scratch database (or from a post-import JSON/SQL projection) inside Laravel via a queued job layer. Feasibility constraints to validate up front: PHP version alignment between the WP-CLI phar and the Laravel runtime (they need not match if containerized, which is the argument for containerizing), MySQL/Postgres bridging (WXR import lands in MySQL; the Laravel side likely isn't), and media/attachment handling, which this command does not fully resolve — attachments are referenced, not downloaded, unless a follow-up step fetches them.
Technical risk.
--skip-style handling; it is not a safe repeatable job.Key questions for the requesting team. (1) Is the actual goal a one-time WordPress content migration, or ongoing bidirectional sync? The latter disqualifies this package. (2) What is the content inventory — custom post types, taxonomies, ACF/meta fields, page-builder payloads, multisite? (3) Are media assets in scope, and who owns fetching and re-hosting them? (4) What is the author/identity mapping story into Laravel's user model? (5) Is a WordPress instance staying live for editorial use post-cutover? (6) Can we confirm the 2026-08-04 release date and pin an exact version? (7) Does legal accept GPL-adjacent tooling in the migration toolchain (MIT here, but WordPress core is GPL)?
Stack fit. Treat this as a migration-stage binary, not a Composer library. It fits a Laravel stack only in the sense that a docker run step in a deployment or migration pipeline fits. Do not add it to composer.json in the application; if you must vendor it for reproducibility, isolate it in a tools/ or migration-specific image so it never enters the app's autoload path or dependency resolution.
Recommended pipeline.
wp import export.xml --authors=create (or a mapping.csv) inside that container.ImportPostJob, ImportTermJob, ImportMediaJob) writing to Eloquent models with an external-ID column for dedupe and re-run safety.Migration path and compatibility. Pin the WP-CLI phar version and the command package version explicitly; WP-CLI packages have historically shifted behavior across minor releases. Keep the scratch WordPress version fixed to the source's version to avoid core-API drift. Ensure the projection schema is committed and versioned so the Laravel importer has a stable contract independent of WP-CLI's internals — this is the main architectural hedge.
Sequencing. Content freeze on WordPress → WXR export → scratch import (validate counts/authors/terms) → projection build → Laravel import in dry-run mode → reconcile diffs → real import → media backfill → URL redirect map → cutover → decommission scratch environment. Each arrow is a gate; do not collapse steps 2–4 into a single "just run the importer" task.
Maintenance. Near-zero if the package is confined to a one-shot migration and the container is deleted afterward. Non-trivial and undesirable if it becomes a standing dependency: you inherit a WP-CLI/WP-core upgrade treadmill for a component that touches nothing in production. Recommendation: time-box it, document the pinned versions, and treat the projection schema, not the package, as the durable asset.
Support. Effectively self-support. Upstream will answer WordPress-runtime questions; it will not support Laravel integration patterns, Postgres targets, or content-model transformations. Internal ownership should sit with whoever owns the migration, with an explicit expectation that debugging means reading WP-CLI source.
Scaling. The importer is single-process and memory-bound. For large sites, plan chunked WXR exports (by date range or post type) and sequential runs, or bypass this package and write a direct WXR/XML reader in Laravel if volume is high enough that the WordPress round-trip is pure overhead. The projection step is where you absorb scale cheaply — it is embarrassingly parallel and re-runnable.
Failure modes to design for. Memory exhaustion or timeout mid-import (leaves partial state — always run against scratch, never a shared target); author mapping collisions and orphaned authors; missing media with broken references surfacing months later; serialized-meta deserialization errors; unrendered shortcodes/blocks producing visually broken pages post-launch; duplicate content on re-run absent external-ID dedupe; and silent taxonomy loss when a custom taxonomy isn't registered in the scratch WordPress instance — this last one is the most common and least visible failure, so validate term counts explicitly.
Ramp-up. Requires WordPress fluency that a Laravel team typically lacks: knowing where postmeta, term relationships, and attachment metadata live, and how to spot a failed import versus a faithful one. Budget a half-day of WP-savvy review per import cycle, or borrow a WordPress engineer for the validation gate. The Laravel-side work (queued importers, external-ID mapping, redirect generation) is the larger and more maintainable share of the effort — staff accordingly, and resist letting the WP-CLI step become the center of the design.
How can I help you explore Laravel packages today?