WP Manifestindependent plugin directory
manifest / updates / idempotent-import

WP Idempotent Import

WP-CLI command that imports a deterministic JSON snapshot produced by WP Idempotent Export into a WordPress site, idempotently and without wiping the destination.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/dhanendran/idempotent-import/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

A WP-CLI command that imports a deterministic JSON snapshot — produced by WP Idempotent Export — into a WordPress site, idempotently and without wiping the destination.

The exporter deliberately preserves source WordPress IDs as canonical identifiers and does no reference rewriting; it leaves ID reissuing and reference rewriting to the importer. This project is that importer.

wp idempotent-import /path/to/snapshot

Re-running the same snapshot against the same destination reconciles against a persisted id-map ledger instead of creating duplicates, so imports are safe to repeat and to resume.

What it does

  • Reads the exporter's tree (manifest.json, posts/, terms/, users/, comments/, options.json) and recreates each entity on the destination.
  • Reissues IDs and rewrites every reference — post author and parent, term hierarchy and assignments, featured images, comment threading, and reference-bearing meta / options — in a second pass, so import order never matters.
  • Never deletes. Existing destination content is matched and merged into by configurable identity rules; only what's missing is created.
  • Idempotent & resumable via a custom ledger table keyed by (source site, entity type, source id).

Built to be extended

Every project migrates differently, so the importer is generic at its core and project-specific at its edges. Three things you'll almost always need are first-class:

  • Meta-key mapping — rename, drop, merge, or retype meta keys (old key → new key), declaratively in config or via a MetaMapper class.
  • User mapping — collapse several source authors into one, remap by rule, reuse existing accounts, or skip — via config or a UserMapper class.
  • Attachment mapping — pluggable strategy, sideload by default (download into the media library), with reference-only, map-to-existing and skip alternatives.

Everything is reachable two ways: lightweight WordPress filters for small tweaks, and a registered class pipeline (resolvers, mappers, strategies, rewriters) for heavier logic. See docs/EXTENDING.md.

Install

Distributed as a WP-CLI package / WordPress plugin.

git clone https://github.com/dhanendran/idempotent-import.git \
    wp-content/plugins/idempotent-import
wp plugin activate idempotent-import

Or include it as a Composer dependency in a plugin/mu-plugin bundle. The plugin only registers itself when WP_CLI is loaded, so it has no front-end cost.

PHP 7.4+ for the runtime. PHP 8.1+ for the test suite.

Quickstart

# Import a full snapshot.
wp idempotent-import /tmp/snapshot

# Use a project import-map (meta renames, user remaps, attachment strategy).
wp idempotent-import /tmp/snapshot --config=migration-map.php

# Preview only — report what would happen, write nothing.
wp idempotent-import /tmp/snapshot --dry-run

# Restrict to some entity types.
wp idempotent-import /tmp/snapshot --only=users,terms,posts

# Keep external/CDN media instead of downloading it.
wp idempotent-import /tmp/snapshot --attachments=reference

A clean run exits zero. Any per-entity skip produces a non-zero exit; skips are listed in import-report.json and report.log written next to the snapshot's manifest.json.

Documentation

  • docs/USAGE.md — every flag, exit codes, recipes.
  • docs/INPUT.md — the snapshot format this importer consumes (the exporter's output contract), and how each field is mapped.
  • docs/ARCHITECTURE.md — the two-phase model, the ledger, module layout, and where to extend.
  • docs/EXTENDING.md — config-driven mapping, filters, and the class pipeline, with worked examples.
  • docs/TESTING.md — running the Pest suite and the in-memory WordPress test double.

Relationship to the exporter

This importer targets the output of darylldoyle/idempotent-export schema 1.x. It mirrors the exporter's conventions deliberately: the same deterministic JSON style for its report, the same skip/warn logging model, the same WP-CLI shape, and an inverse of the exporter's slash handling so that export → import → re-export stays byte-stable.

Non-goals

  • Network-wide multisite import. One site at a time.
  • Migrating binary media beyond the sideload strategy.
  • Importing plugin custom tables (HPOS, Gravity Forms, etc.) — the exporter doesn't emit them yet; when it does (via its planned third-party-table hook), a matching importer hook will consume them.
  • Validating the source schema.

License

MIT.