In this first article you will learn how to base your WordPress and WooCommerce project entirely on Composer and on WPackagist. The actual performance boost this will give you depends on how old your current WordPress core and plugin versions currently are.

The main focus in this first tutorial is somewhere, though. Updating the core and plugins is very important because your store will benefit from improved performance and improved security. Unfortunately updating WordPress Core, Plugins and Themes can be very time consuming. WordPress 5.6 introduced an improved update and upgrade logic. That said, it’s still far from optimal and still does not give the control or stability one needs in Ecommerce. When using modern techniques like Composer, WPackagist, GitHub and so on, you are making the process of updating the core and/or plugins easier and faster. That’s why I consider this first (and longest) tutorial of this series the most important one.

As a side note I would like to mention the excellent Bedrock framework here as well. It does exactly what we want to achieve in this tutorial: to base your WordPress & WooCommerce environment on Composer, WPackagist and also establish a solid project structure. That said, in order to learn how to use WordPress with composer, we want to get our hands dirty with some real code examples – so I will guide you through a manual setup step by step.

To get started, let’s see how a WordPress setup is done using Composer. Even with an existing project & codebase, you can do this step. Once the setup is done you would just add your plugins and themes to it.

Step 1: Create the project

Since I use macOS, I install Composer with Homebrew. Alternatively, you could also follow the installation instructions on the Composer website to install Composer without brew.

brew install composermkdir -p ~/Sites/my-projectcd ~/Sites/my-projectcomposer init

This installed composer, created a directory for our project and starts the composer init wizard, which helps us create our composer.json file.

Like in my screenshot, choose a project handle, description, confirm your author info, set stability to stable, set a project type project and choose the following package dependencies. When asked wether to install these dependencies right away, write no. We want to make adjustments to the composer.json before we actually install our dependencies.

  • composer/installers
  • johnpbloch/wordpress-core-installer
  • johnpbloch/wordpress-core
  • drupal-composer/preserve-paths

By leaving the version constraint empty, composer automatically detects the latest (stable) version of the package, as you can see below.

Step 2: Modify the composer.json

Open the newly created composer.json with an editor of your choice (for example nano) and add this right before the closing bracket of the JSON object.

composer.json,"repositories" : [{  "type" : "composer",  "url" : ""}, {  "type" : "composer",  "url" : ""}],"extra" : {  "installer-paths" : {  "wordpress/wp-content/plugins/{$name}/" : [    "type:wordpress-plugin"  ],  "wordpress/wp-content/themes/{$name}/" : [    "type:wordpress-theme"  ]},  "wordpress-install-dir" : "wordpress",  "preserve-paths" : [    "wordpress/robots.txt",    "wordpress/wp-config.php",    "wordpress/wp-content/themes/storefront-child",    "wordpress/wp-content/plugins/perfmatters"  ]}

Explanation: the first repositories section adds the wpackagist sources to composer which allows us installing and updating plugins and themes from’s directory with composer.
The second part under extra, defines where packages of the types wordpress-plugin and wordpress-theme are installed to.
Then there is the installation location where WordPress is going to be installed to, namely a subdirectory by the name of wordpress. You might adjust this if you prefer ‘public’ or ‘web’ for example. This will also be your Document Root, later on.
And finally, a list of paths inside the preserve-paths section is for files or folders, from the following categories:

  1. files or folders you want in your repository although they are not a part of the WordPress Core. So for example a  robots.txt which you want to be part of your repository. Also your customised wp-config.php should be listed here, or your theme and child theme which you will add later on. Otherwise these files would be lost and replaced with what’s in the original repository each time composer update/install is executed. We don’t want that, so we add these here. This is a good reason to add an entry to the preserve-paths section.
  2. paid plugins or old plugins that are not available on wpackagist or github. If a plugin is not available for automatic installation via our dependency manager, we can just drop it into the wordpress/wp-content/plugins folder. When we run composer update or composer install to update all the other plugins or the WordPress core, composer doesn’t know about this plugin, so it would remove it. This is why we add these plugins to the preserve-paths section as well. You should avoid adding old or paid plugins if possible since updating them is a rather manual process and it undermines the idea of dependency management.
  3. files and folders from either the WordPress Core or a Plugin which you have to modify because there’s no hook or filter you can take advantage of in order to achieve what you need. After running composer update or install, the core modifications you made would be lost – because composer replaces it with the latest and greatest version of these files.

The complete composer.json should look like this now:

composer.json{    "name": "vardumper/my-project",    "description": "Initial WordPress & Composer project setup with composer",    "type": "project",    "require": {        "composer/installers": "^1.9",        "johnpbloch/wordpress-core-installer": "^2.0",        "johnpbloch/wordpress-core": "^5.6",        "drupal-composer/preserve-paths": "^0.1.6"    },    "license": "GPL",    "authors": [        {            "name": "vardumper",            "email": "[email protected]"        }    ],    "minimum-stability": "stable",    "repositories" : [{        "type" : "composer",        "url" : ""    }, {         "type" : "composer",         "url" : ""    }],    "extra" : {        "installer-paths" : {            "wordpress/wp-content/plugins/{$name}/" : [                "type:wordpress-plugin"            ],            "wordpress/wp-content/themes/{$name}/" : [                "type:wordpress-theme"            ]        },        "wordpress-install-dir" : "wordpress",        "preserve-paths" : [            "wordpress/robots.txt",            "wordpress/wp-config.php",            "wordpress/wp-content/themes/storefront-child",            "wordpress/wp-content/plugins/perfmatters"        ]    }}

Step 3: Ready to install

We’re good to go now, so let’s install everything.
Simply run composer install.

Step 4: Install or add your theme

Here you have several options:

Option 1: If you already have a running WooCommerce store with a custom made theme, then add your theme now.
Simply copy your existing theme folder into the wordpress/wp-content/themes directory and then add its full path to the preserve-paths section of the composer.json like I did above with storefront-child (or simply change storefront-child to your theme name for that matter).

Option 2: You want to use a pre-made theme available on wpackagist (for example Storefront) then simply install it with:
composer require wpackagist-theme/storefront
And as it is a common practice with WordPress, you will want to extend it by creating a child theme in your theme folder.
All you need is the new folder storefront-child, and a style.css inside with:

wordpress/wp-content/themes/storefront-child/style.css/**Theme Name: Storefront ChildDescription: This is a child theme for Storefront ThemeAuthor: MyselfTemplate: storefrontVersion: 1.0*/

Finally, don’t forget to add your child themes path to the preserve-paths section of your composer.json like I have done it in the composer.json above. If you don’t do so, installing or updating your project with composer will remove your child theme folder from the themes directory.

Option 3: You want to use one of WordPress default themes. Then you’re all set.

Step 5: Add WooCommerce

Type composer require wpackagist-plugin/woocommerce and hit enter. This installs WooCommerce.

Step 6: Database setup and Server start

If you don’t have MySQL installed yet, install it. I highly recommend you to use the latest version 8.0 on all of your server(s). Use brew install mysql or download the latest installer from the download page. Then connect to MySQL with mysql -u root -p and create a local MySQL user and database:

CREATE DATABASE `my-project`;CREATE USER 'my-project'@'localhost' IDENTIFIED WITH mysql_native_password BY 'my-password';GRANT ALL PRIVILEGES ON `my-project`.* TO 'my-project'@'localhost' WITH GRANT OPTION;FLUSH PRIVILEGES;

Every web developer has their own preferences in regards to the server, some use MAMP, XAMPP, most developers have heard of Docker, Vagrant, Laravel Homestead. Others prefer installing PHP & Nginx/Apache. And so on so forth. Personally I prefer Laravel Valet but for the sake of simplicity, let’s use PHP’s built-in server right now:

php -S localhost:8080 -t wordpress

For simplicity you can add a script to composer.json which runs exactly that line.

"scripts" : {	"serve" : "php -S localhost:8080 -t wordpress &> /dev/null"}

This way you can type composer serve to start the server.

Now open http://localhost:8080 in your browser. You will be guided through WordPress’s install routine. After finishing the installation in the browser, activate your new storefront-child theme, and activate WooCommerce.

Adding, removing and updating plugins

Now that was easy. WordPress is installed. Now how do you work with Composer?

composer require wpackagist-plugin/manage-notification-emails # add a plugincomposer remove wpackagist-plugin/woocommerce # remove a plugincomposer update wpackagist-plugin/woocommerce # update a single package

Updating the WordPress core and plugins at once

Let’s say there’s a new WordPress release. Or maybe a plugin you’re using has some important security or performance improvements. Or some weeks or months have passed and you just want to update plugins and wordpress. All you need to do now is a simple: composer update

To make and to keep updates as hassle-free as possible, avoid paid, closed-source plugins wherever you can. Updating such a plugin requires manual steps (downloading the upgrade, uploading it to your server or repo and additional installation steps). This also helps you to simplify the automation of your deployment process which we will look at later in part 4 of this tutorial series.

Download Tutorial: Setting Up WordPress & WooCommerce with Composer (30.6 MB)

Let’s continue with part 2 “Using an .env file for database and other credentials