Local development environments for WordPress.org projects, powered by wp-env.
From the environments/ directory:
npm installA local instance of the WordPress.org Plugin Directory with the plugin directory plugin, theme, and supporting mu-plugins.
Start:
npm run plugins:env startImport a plugin by slug:
npm run plugins:import -- akismetRe-seed plugins (clears import flag, then re-imports):
npm run plugins:refreshAccess: http://localhost:8888
WP CLI:
npx wp-env run cli wp <command>Run tests:
npm run plugins:testA local instance of the WordPress.org Theme Directory with the theme directory plugin, Theme Check, the wporg-themes-2024 frontend theme, and supporting mu-plugins. Themes are imported from the live WordPress.org themes API.
Start:
npm run themes:env startRe-import themes (on demand, without clearing existing data):
npm run themes:importRe-seed themes (clears import flag, then re-imports):
npm run themes:refreshAccess: http://localhost:8888
WP CLI:
npm run themes:env -- run cli -- wp <command>Run tests:
npm run themes:testA local instance of jobs.wordpress.net with the JobsWP plugin, theme, sample job categories, and sample job posts.
Start:
npm run jobs:env startAccess: http://localhost:8888
WP CLI:
npm run jobs:env -- run cli -- wp <command>A local instance of browsehappy.com with the theme.
Start:
npm run browsehappy:env startAccess: http://localhost:8888
A local instance of translate.wordpress.org with GlotPress, the wporg-gp-* plugins active on production, and the pub/wporg theme.
Start:
npm run translate:env startFirst start auto-imports hello-dolly (plugin) and twentytwenty (theme) so the WordPress Plugins and WordPress Themes project containers have real fixtures. It also seeds a few demo Translation Events (active, upcoming, past, and draft) with hosts and attendees.
Access: http://localhost:8888
Users: admin / password is a GlotPress global administrator, so it can approve translations everywhere and never sees a permission check fail. translator / password is a plain subscriber with no GlotPress permissions — use it to check what a contributor sees, such as suggestions going to waiting instead of current. The dev login button fills in admin, so type the contributor credentials by hand.
Import a plugin or theme's translations on demand:
npm run translate:import -- plugin akismet
npm run translate:import -- theme twentytwentyfourSeed demo events on demand (idempotent):
npm run translate:seed-eventsRe-seed (clears the seed flag so the next start re-imports fixtures):
npm run translate:refreshWP CLI:
npm run translate:env -- run cli -- wp <command>Run tests (the Translation Events plugin's PHPUnit suite, in a dedicated test environment):
npm run translate:testLocal overrides: create translate/.wp-env.override.json (git-ignored) to override config values like WP_HOME / WP_SITEURL for testing behind a custom hostname.
Translation Events 2024 design: the events routes render the legacy templates unless the new block theme is enabled. To preview it, add "config": { "TRANSLATION_EVENTS_NEW_DESIGN": true } to translate/.wp-env.override.json and restart.
A local instance of the WordPress.org Support Forums with bbPress, the wporg-support-2024 theme, and the wporg-bbp-* supporting plugins. It runs as a multisite network, because the forums read the plugin and theme directories out of sibling sub-sites.
Start:
npm run support:env startAccess: http://localhost:8888
Re-seed (clears the seed flag, then re-runs the seed):
npm run support:refreshWP CLI:
npm run support:env -- run cli -- wp <command>Add --url=localhost:8888/rosetta (or /plugins, /themes) to target a sub-site.
The network:
| Blog | Path | Purpose |
|---|---|---|
| 1 | / |
The global support forums — the site under development |
| 2 | /plugins |
Plugin Directory, a dependency of the /plugin/<slug>/ forum views |
| 3 | /themes |
Theme Directory, a dependency of the /theme/<slug>/ forum views |
| 4 | /rosetta |
A locale ("Rosetta") forum, for the locale-only code paths |
The blog IDs are pinned in .wp-env.json (WPORG_PLUGIN_DIRECTORY_BLOGID and friends), so the seed creates the sub-sites in that order and fails loudly if they come out differently.
Note that the plugin and theme directories here exist only as forum dependencies. Use the Plugin Directory and Theme Directory environments to work on the directories themselves.
On production each locale forum is its own network with IS_ROSETTA_NETWORK defined, which a single wp-config.php cannot express. mocks/mu-plugins/wporg-support-env.php defines it for the blog named by WPORG_LOCAL_ROSETTA_BLOGID instead.
Forum IDs: the Plugins, Themes and Reviews forums are created as the post IDs that Plugin::PLUGINS_FORUM_ID and Support_Compat::HIDDEN_FORUMS hard-code for production (21261, 21262, 21272, plus two legacy IDs). The directory compat views, the review forum, and the hidden-forum filtering all key off those, so they cannot be left to auto-increment.
What to try: hello-dolly is seeded on the plugin directory with a committer, a contributor and a support rep; twentytwentyfour is seeded on the theme directory with an author. Visit /plugin/hello-dolly/, /theme/twentytwentyfour/, and either followed by reviews/. Ratings submitted through the review form persist in the local ratings table, so the star filters and rating edits work.
Local boundaries. The environment deliberately does not reach production:
- Badge assignments would otherwise be a live POST to
profiles.wordpress.org.Badge_Automationregisters its hooks locally, becauseassign_badge()lives in the mountedmu-plugins/pub/profile-helpers.php, andProfiles\queue()dispatches synchronously for anything that is notproductionwhileapi()only redirects the URL forstaging.mocks/mu-plugins/wporg-profiles-local.phpanswers those requests and records the associations in local tables. - Outbound mail is short-circuited; the forums mail on subscriptions, moderation and reports.
WPORG_Ratingsis a local stand-in.Ratings_Compatguards onclass_exists()alone, so the stub implements every method it calls rather than a subset.- SSO, two-factor account management and the rest of the Profiles service are not reproduced.
User accounts:
All accounts use the password password.
| Username | Role on / |
Role on /rosetta |
Notes |
|---|---|---|---|
admin |
Network administrator | Network administrator | Full network admin access |
keymaster |
bbp_keymaster |
bbp_participant |
Top-level forum admin; can manage all forum content |
moderator |
bbp_moderator |
bbp_participant |
Can moderate topics and replies |
rosettakeymaster |
bbp_participant |
bbp_keymaster |
Keymaster of the locale forum |
rosettamoderator |
bbp_participant |
bbp_moderator |
Moderator of the locale forum |
pluginauthor |
bbp_participant |
bbp_participant |
Committer on the seeded Hello Dolly plugin |
plugincontributor |
bbp_participant |
bbp_participant |
Contributor on the seeded Hello Dolly plugin |
pluginsupport |
bbp_participant |
bbp_participant |
Support rep on the seeded Hello Dolly plugin |
themeauthor |
bbp_participant |
bbp_participant |
Author of the seeded Twenty Twenty-Four theme |
themesupport |
bbp_participant |
bbp_participant |
Theme support rep; no production equivalent yet |
visitor |
bbp_participant |
bbp_participant |
Regular forum visitor |
Block editor: the forums use the block editor through Blocks Everywhere, which is not installed here — it needs a Gutenberg old enough to break against WordPress trunk until Automattic/blocks-everywhere#211 lands. Plugin::__construct() loads the block support only when that plugin is present, so the environment runs on bbPress' plain editor until then.
A test-only environment for the shared single sign-on code in common/includes/wporg-sso/. The SSO is a library rather than a plugin, so it is mounted at wp-content/wporg-sso instead of being activated, and its PHPUnit suite runs from there.
WP_ENVIRONMENT_TYPE is set to production so the SSO uses the hosts it uses in production (login.wordpress.org and friends) rather than the shortcuts it takes on local installs.
Run tests:
npm run sso:testThe Handbook plugin has its own .wp-env.json in wordpress.org/public_html/wp-content/plugins/handbook/.
Start:
cd wordpress.org/public_html/wp-content/plugins/handbook
npx wp-env startRun tests: use the test environment in this directory instead — it starts a dedicated instance and runs the suite in one step:
npm run handbook:test# Stop an environment (replace plugins with jobs, etc.)
npm run plugins:env stop
npm run jobs:env stop
# Destroy an environment (removes all data)
npm run plugins:env destroy
npm run jobs:env destroy
# View logs
npm run plugins:env logs
npm run jobs:env logsAll commands should be run from the environments/ directory unless otherwise noted.