theme-elementary

Local development

This guide covers day-to-day work on an initialized theme: running WordPress locally, editing source and seeing the result, checking a change, and building for delivery. Start here after initialization. Commands run from the theme directory; examples assume the folder is acme-blog.

Start and stop WordPress

npm run wp-env start
npm run wp-env run cli -- wp theme activate acme-blog

The development site is http://localhost:5890. PHP tests use a separate environment, defined in .wp-env.tests.json, on http://localhost:5891 with its own database; npm run test:php starts it when needed. Activation uses the mounted folder name, not the theme display name or text domain. When you finish, stop the environments with:

npm run wp-env stop
npm run wp-env -- stop --config=.wp-env.tests.json

For an existing local WordPress installation, use its normal startup and activation process instead, then run the theme-local commands from this directory.

Edit source and see the result

Edit Output / purpose
theme.json, templates/, parts/, patterns/, styles/ WordPress theme configuration and block markup; no asset compilation needed.
src/css/, src/js/ Compiled under assets/build/css/ and assets/build/js/.
src/js/frontend/modules/ Interactivity modules under assets/build/js/modules/.
src/components/<name>/<name>.{js,scss} assets/build/js/components/<name>.js and assets/build/css/components/<name>.css; the component PHP stays under src/components/.
src/blocks/ (when added) Block files under assets/build/blocks/.
inc/, template-parts/ PHP behavior and render templates.

Edit files under src/, inc/, templates/, parts/, patterns/, and styles/. Treat everything under assets/build/ as generated output; do not edit it by hand.

Use npm run start:assets for theme assets. When you add custom blocks, npm run start:blocks watches their sources with the block dev server. npm start runs both watchers. These commands stay running until Ctrl+C.

With start:assets, edit a stylesheet or script and confirm the watcher writes the matching file under assets/build/; BrowserSync then injects CSS or reloads the frontend. For template and block markup, refresh the frontend or Site Editor after the build. With start:blocks, edit a custom block and confirm the editor refreshes and the browser console has no build error. Whichever watcher you’re using, a visible source change reaching the active site is the basic success check — if it doesn’t show up, that’s the first thing to debug before writing more code.

For a one-time development build, use npm run build:dev. See Asset builds for entry naming and enqueueing.

Automatic frontend reload

For the default HTTP wp-env site, add the following to .env.local, preserving any existing settings:

WP_HOST=localhost
ENABLE_HMR=true
BS_PORT=3001

The wp-env development environment already sets WP_ENVIRONMENT_TYPE=local, WP_DEBUG=true, and SCRIPT_DEBUG=true. For another local WordPress installation, set those values in its wp-config.php before using live reload. Restart wp-env after configuration changes, then start the watcher.

For HTTPS, custom ports, or block refresh, read Live reload. Leave WP_SSL_KEY and WP_SSL_CERT unset in .env.local for an HTTP setup.

Check a change

Run these once, from the host machine, before committing or opening a PR — they’re the same checks CI runs, just faster to iterate on locally:

npm run test:js -- --runInBand --watch=false
npm run lint:js
npm run lint:css
npm run lint:package-json
composer phpcs
composer phpstan

npm run lint:js reads eslint.config.mjs, npm run lint:css reads .stylelintrc.json, composer phpcs reads phpcs.xml.dist (the WordPress Theme Coding Standards), and composer phpstan reads phpstan.neon.dist — edit those files to change the actual rules.

For a focused JavaScript test, add its path while keeping watch mode off:

npm run test:js -- --runInBand --watch=false tests/js/webpack-config.test.js

Use PHP compatible with the project’s installed checks (PHP 8.2 is the wp-env baseline). To run PHPCS in that container instead:

npm run wp-env -- run cli --env-cwd=/var/www/html/wp-content/themes/acme-blog -- vendor/bin/phpcs

The theme’s PHP test command runs inside the test environment’s cli container; its pretest hook starts that environment and installs Composer dependencies there without scripts. The test environment has WP_DEBUG on, which the logger tests need.

npm run test:php

For a focused PHP test:

npm run wp-env -- run --config=.wp-env.tests.json cli --env-cwd=/var/www/html/wp-content/themes/acme-blog -- vendor/bin/phpunit --filter AuthorBioTest

Use the relevant test name if the example was removed. Keep smoke projects outside this repository so Jest does not discover another project’s tests. Use the explicit commands above for a terminating review check; aggregate-script details belong in maintenance.

Build for delivery

npm run build:prod

Verify assets/build/ contains the CSS, JavaScript, metadata, and any custom blocks needed by the theme. The directory is gitignored: commit source and build configuration, not the build output itself, and make sure your deployment process runs this build (or an equivalent) before the theme goes live. This starter theme does not define your project’s deployment pipeline — that decision is yours.

Review visible behavior and checks before feature integration; make a separate feature commit when that checkpoint is useful for your workflow.

Troubleshooting

Symptom Check → next action
wp-env cannot start Run docker info; start Docker and retry if unavailable. For an occupied port, set WP_ENV_PORT, for example WP_ENV_PORT=5892 npm run wp-env start or WP_ENV_PORT=5893 npm run test:php.
Frontend assets return 404 Check assets/build/; run npm run build:dev and confirm the theme is active.
CSS rebuilds but no live reload Confirm local environment type, watcher, and BrowserSync port; see HMR.
HTTPS reload is blocked Check that WP_SSL_KEY and WP_SSL_CERT point to trusted certificates for the site hostname; see HMR.
Site Editor ignores a template file edit Check for a customized template saved in WordPress; review/reset that customization before testing the file version.
PHP tests cannot connect Start wp-env and rerun npm run test:php.
New PHP feature does not load Check namespace/path and Main::CLASSES; see Development.