Development environment

Starting by saying that with a

yarn run server

you should be up and running, let’s see in depth what happens behind the scenes.


yarn run (or simply yarn scriptName) will search for a scripts section inside your package.json file and will execute the matched script.

  "scripts": {
    "server": "npx nf start",
    "build:dev": "webpack --env NODE_ENV=development",
    "build:prod": "yarn sign-release && webpack --env NODE_ENV=production",
    "clean:js": "rimraf dist/javascripts/*",
    "clean:css": "rimraf dist/stylesheets/*",
    "clean:images": "rimraf dist/images/*",
    "clean:dist": "yarn clean:js && yarn clean:css && yarn clean:images",
    "sign-release": "git rev-parse HEAD | cut -c 1-8 > release.txt",
    "lint": "yarn lint:sass",
    "lint:sass": "npx stylelint 'src/stylesheets/**/*.scss'",
    "test:db:create": "WP_ENV=test wp db create",
    "test:db:drop": "WP_ENV=test wp db drop",
    "test:db:snapshot": "mv tests/_data/dump.sql tests/_data/dump_$(date +%s).sql; wp db export tests/_data/dump.sql",
    "test:db:setup": "WP_ENV=test yarn test:db:drop; WP_ENV=test yarn test:db:create; yarn test:db:snapshot",
    "test:setup": "wp wordless theme setup_test_suite && yarn test:db:setup && composer install && php ./vendor/bin/codecept build",
    "test:server": "npx nf start --procfile Procfile.testing --env .env.testing",
    "test": "vendor/bin/codecept run acceptance",
    "setup": "yarn install && yarn test:setup"

yarn server will run nf start, where nf is the Node Foreman executable.


Node Foreman (nf) could do complex things, but Wordless uses it only to be able to launch multiple processes when server is fired.

wp: wp server --host=
webpack: npx webpack --watch --progress --color --env NODE_ENV=development
mailhog: mailhog

As you can see, each line has a simple named command. Each command will be launched and foreman will:

  • run all the listed processes
  • collect all STDOUTs from processes and print theme as one - with fanciness
  • when stopped (CTRL-C) it will stop all of the processes

wp server

Launched by nf. Is a default WP-CLI command.

We are invoking it within a theme directory, but it will climb up directories until it finds a wp-config.php file, then it will start a PHP server on its default port (8080) and on the address as per our config.


You can directly reach in you browser in order to reach wordpress, bypassing all the webpack things we’re going to show below.


The only relevant Webpack part in this section is BrowserSync. It will start a web server at address on port 3000. This is where your browser will automatically go once launched.

        watchOptions: {
          ignoreInitial: true
        files: [

      new MiniCssExtractPlugin({
        filename: 'stylesheets/[name].css'

      new CopyWebpackPlugin({

As you can see from the configuration, web requests will be proxy-ed to the underlying wp server.

Since BrowserSync is invoked through a Webpack plugin (browser-sync-webpack-plugin) we will benefit from automatic browser auto-reloading when assets are recompiled by Webpack itself.

The files option is there because .pug files are not compiled by webpack, so we force watching those files too, thus calling auto-reload on template changes too.

See also

Code compilation for other Webpack default configurations


BrowserSync’s UI will be reachable at as per default configuration.


If you will develop with the WordPress backend in a tab, BrowserSync will ignorantly reload that tab as well (all tabs opened on port 3000 actually). This could slow down your server. We advise to use the WordPress backend using port 8080 and thus bypassing BrowserSync.


MailHog is an email testing tool for developers:

  • Configure your application to use MailHog for SMTP delivery
  • View messages in the web UI, or retrieve them with the JSON API
  • Optionally release messages to real SMTP servers for delivery

Wordless is configured to use it by default, so you can test outgoing emails from your site, from WordPress and from your forms.

The UI will be at http://localhost:8025 as per default configuration.

When you spawn yarn server, you’ll have an environment variable exported thanks to the .env file:


This will trigger the smtp.php initializer:


add_action( 'phpmailer_init', 'wl_phpmailer_init' );
function wl_phpmailer_init( PHPMailer\PHPMailer\PHPMailer $phpmailer ) {
    $mailhog = getenv('MAILHOG');

    if ($mailhog !== "true")
      return false;

    $phpmailer->Host = 'localhost';
    $phpmailer->Port = 1025;
    // $phpmailer->SMTPAuth = true;
    // $phpmailer->Username = 'user';
    // $phpmailer->Password = 'password';
    // $phpmailer->SMTPSecure = 'ssl'; // enable if required, 'tls' is another possible value

Debug in VSCode

We ship a .vscode/launch.json in theme’s root which is pre-configured to launch debugger for XDebug and for JS (both Chrome and FireFox). In order to use these configuration you’ll need to install some plugins in the editor:


You may need to move .vscode/launch.json in another location if you are not opening the theme’s folder as workspace in VSCode (maybe you prefer to open all the WordPress installation? Don’t know…). It’s up to you to use it as you need it.