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": "nf start",
    "build:dev": "webpack --debug --env.WL_ENV=development",
    "build:prod": "webpack -p --bail --env.WL_ENV=production",
    "clean:js": "rimraf assets/javascripts/**.js assets/javascripts/**.map",
    "clean:css": "rimraf assets/stylesheets/**.css assets/stylesheets/**.map",
    "clean:images": "rimraf assets/images/**.{png,gif,jpg,svg}",
    "clean:dist": "yarn clean:js && yarn clean:css && yarn clean:images"

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


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

wp: wp server --host=
webpack: npx webpack --debug --watch --progress --color --env.WL_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 fancyness
  • 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.
    plugins: [
      new BrowserSyncPlugin {
          host: ""
          port: 3000
          proxy: { target: "" }
          watchOptions: { ignoreInitial: true }
          files: [

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 autoreloading 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 autoreload 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 mailouts 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 ) {
    $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