This repository includes tools for starting a local development environment using @wordpress/env, which requires Docker and Docker Compose. In addition, both npm and composer are required to install the local dependencies.
Both sites are served on the host.docker.internal hostname so each container reaches the other at the same address WordPress emits in its URLs. Docker Desktop resolves the name inside containers; the host machine doesn't by default. Add a one-line entry so your browser can reach either site at the same URL the containers use internally:
echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hostsWithout this, browsing either site from your machine fails, and source URLs baked into imported content (image src, links) won't resolve when previewing posts in the destination admin.
Clone this repository and install its dependencies:
npm installTo start a development environment with Xdebug enabled:
npm run devThis will spin up two WordPress environments, build the block editor scripts, set the shared secrets, and watch for changes.
Both WordPress environments are served on host.docker.internal (admin user: admin, password: password):
- Destination:
http://host.docker.internal:8888 - Source:
http://host.docker.internal:8889
The same hostname is used from your browser and from inside either container, so cross-container HTTP calls and HMAC validation both line up against the same canonical URL.
Stop the development environment with Ctrl+C and resume it by running the same command. You can also manually stop the environment with npm run dev:stop. Stopping the environment optionally stops the WordPress containers but preserves their state.
To run additional checkouts (e.g. git worktree siblings) alongside the main one, each worktree's wp-env needs its own port pair so it doesn't collide with other running wp-envs. From the worktree, run:
bin/setup-worktreeThe script installs dependencies and prints the next free WP_ENV_PORT and WP_ENV_TESTS_PORT pair (8890/8891 for the first worktree, 8892/8893 for the next, and so on). Then start wp-env with the printed values:
WP_ENV_PORT=8890 WP_ENV_TESTS_PORT=8891 npm run devWhen you're done with a worktree, tear it down so containers and volumes don't orphan:
# From inside the worktree:
npm run dev:destroy
# Then from another worktree (e.g. the main checkout):
git worktree remove ../<worktree-dir>Skipping dev:destroy before removing leaves wp-env containers and volumes behind, identifiable via docker ps -a and docker volume ls.
For local development, you'll need two WordPress sites to test import functionality:
- Source site (non-production) - Where content comes from
- Destination site (your dev environment) - Where content is imported to
To populate the source or destination site with realistic test content for manual testing or import verification, see Content Seeding.
To seed the Needs attention tab for UI testing, see Seeding Import Degradations.
Before committing, validate and fix code quality:
# Check all code (linting, formatting, types)
npm run check
# Auto-fix all fixable issues
npm run fixThe pre-commit hook automatically runs linting and formatting on staged files, auto-fixing what it can and blocking commits with unfixable errors.
Run unit tests:
# all unit tests
npm run test
# only JavaScript unit tests
npm run test:js
# only PHP unit tests
npm run test:php
# only a specific test file
npm run test:js some/test/file.js
npm run test:php -- --filter SomeTestClassFor e2e tests, ensure the development environment is running, then execute:
npm run test:e2eWatch logs from the WordPress container:
npx wp-env logsRun WP-CLI commands:
npm run wp-cli option get siteurlDestroy your local environment and irreversibly delete all content, configuration, and data:
npm run dev:destroyThe development environment includes:
- Xdebug for PHP debugging (port 9003)
- Node.js debugging port for JavaScript debugging
Enable WordPress debug mode:
Add to wp-config.php in your local environment:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );View debug logs:
tail -f wp-content/debug.logVSCode users: You can rename .vscode/launch.json.example to .vscode/launch.json to enable Xdebug debugging in the editor.
Access the MySQL database:
# View import sessions
npm run wp-cli db query "SELECT * FROM wp_safe_publish_imports LIMIT 10"
# View import items
npm run wp-cli db query "SELECT * FROM wp_safe_publish_import_items LIMIT 10"
# View audit log events
npm run wp-cli db query "SELECT * FROM wp_safe_publish_audit_log LIMIT 10"
# Or connect directly
docker exec -it <container-id> mysql -u root -ppassword wordpressReset plugin settings or clear import history:
See the Troubleshooting guide.
Test authentication:
Use the Test Connection button on the settings page.
While not suitable for local development, it can sometimes be useful to quickly spin up a local WordPress playground:
npm run build # or `npm start` in a separate terminal
npm run playgroundPlaygrounds do not closely mirror production environments and are missing persistent object cache, debugging tools, and other important features. Use npm run dev for local development.
- Use two browser windows - one for source site, one for destination.
- Test with different post types - posts, pages, custom types.
- Test media import - posts with multiple images.
- Check the Imports page - verify the Posts and Needs attention tabs reflect each attempt.
- Monitor network requests - use browser DevTools.
- Test error conditions - invalid URLs, auth failures, etc.
See the Troubleshooting Guide for more help.