PMG Digital Made for Humans

A Gentle Introduction to Using Composer with WordPress

5 MINUTE READ | May 6, 2015

A Gentle Introduction to Using Composer with WordPress

Author's headshot

Christopher Davis

Christopher Davis has written this article. More details coming soon.

WordPress and Composer

Composer is a dependency manager for PHP. If you’ve done any modern PHP development in the last few years, you’ve probably used it. Packagist is a composer repository — a place where composer can look up packages (libraries) that are installable.

This post is going to cover why you should use a dependency manager and how to get started integrating Composer with your WordPress site.

Code reuse is a good thing — your clients aren’t paying you to reinvent the wheel, they’re paying you to build them a website or application. Chances are you already know this, so you have a set of go to plugins that you use on every WordPress site you build. You’re already using other peoples code via plugins, but there’s an entire world of modern PHP libraries available to you via composer.

Someone has also taken it upon themselves to make every plugin available as a composer dependency.

A dependency manager can be part of your build pipeline and keep 3rd party code out of your source repository. It also opens up a lot of opportunity to use otherwise unavailable PHP libraries.

If you’re one of those folks who likes to hack apart plugins to make them do what you want (and then have your changes destroyed by a plugin update), a dependency manager will force you to think a bit differently about how to accomplish those goals.

Since you’ve been at this a while, you know putting WordPress in a subdirectory is the way to go. Maybe you’ve used a submodule like Mark Jaquith suggests.

That’s awesome! It gives us a starting point with composer: let’s convert that WordPress submodule to a composer dependency.

First off, you’ll need to remove the submodule. We’re not going to cover that here.

Composer installs libraries into vendor directory at the root of your project. Specifically each package goes into vendor/{vendorName}/{libraryName} by default. An installer lets you change that behavior based on the type of package. Because WordPress isn’t really a library (it’s more of an application, with static assets) we need to install it in a custom location somewhere on the document root.

Fortunately, we don’t have to build that ourselves because it already exists.

You define composer dependencies with a composer.json file at the root of your project. There’s an auto updated fork of WordPress that includes a composer.json file of it’s own and is on packagist.

The most bare bones composer file include the WordPress installer and WordPress itself as a dependency and that’s it. There’s also an extra section where you tell the WP installer where to put WordPress.


{    "name": "pmg/composer-wp-example",    "description": "Getting start with WordPress and Composer",    "license": "MIT",    "require": {        "php": ">=5.5",        "johnpbloch/wordpress-core-installer": "0.2.0",        "johnpbloch/wordpress": "~4.2"    },    "extra": {        "wordpress-install-dir": "wp"    }}

The above will install WordPress in the wp directory. Assuming you’ve installed composer, you can now run composer install from the command line.

Listing our new directory, we can see WordPress, a new

directory, and a composer.lock file.

wp-composer-example$ ls composer.json composer.lock vendor wp

So we’ve got WordPress installed, let’s install some plugins with composer! Remember the installer bit above? There’s also custom installers for WordPress plugins and themes as part of the composer/installers library. So let’s pull that in and tell composer where to put things. The file path’s below assume you’ve set content to be the wp-content folder.

To install plugins as a composer dependencies form WP Packagist we also need to add it as a repository in our composer.json file. Our new file looks like this:


{    "name": "pmg/composer-wp-example",    "description": "Getting start with WordPress and Composer",    "license": "MIT",    "repositories": [        {            "type":"composer",            "url":""        }    ],    "require": {        "php": ">=5.5",        "johnpbloch/wordpress-core-installer": "0.2.0",        "johnpbloch/wordpress": "~4.2",        "composer/installers": "~1.0"    },    "extra": {        "wordpress-install-dir": "wp",        "installer-paths": {            "content/plugins/{$name}": ["type:wordpress-plugin"],            "content/themes/{$name}": ["type:wordpress-theme"],            "content/mu-plugins/{$name}": ["type:wordpress-muplugin"]        }    }}

Let’s install WordPress SEO as a dependency:


{    "name": "pmg/composer-wp-example",    "description": "Getting start with WordPress and Composer",    "license": "MIT",    "repositories": [        {            "type":"composer",            "url":""        }    ],    "require": {        "php": ">=5.5",        "johnpbloch/wordpress-core-installer": "0.2.0",        "johnpbloch/wordpress": "~4.2",        "composer/installers": "~1.0",        "wpackagist-plugin/wordpress-seo": "~2.1"    },    "extra": {        "wordpress-install-dir": "wp",        "installer-paths": {            "content/plugins/{$name}": ["type:wordpress-plugin"],            "content/themes/{$name}": ["type:wordpress-theme"],            "content/mu-plugins/{$name}": ["type:wordpress-muplugin"]        }    }}

After a run of composer update from the command line, we we now have a content directory containing our newly installed plugin!

wp-composer-example$ ls composer.json composer.lock content vendor wp wp-composer-example$ ls wp-content/plugins/ wordpress-seo

Ideally you deploy your WordPress site in such a way that the vendor folder and your composer.{lock,json} files are not on your document root and are inaccessible to the public. If you’re taking the first steps using composer that might not be the case, so you can block those files with server configuration.


RewriteEngine onRewriteRule ^composer\.(lock|json)$ - [F,L]RewriteRule ^vendor/.*$ - [F,L]


server {  host    # ...    location ~ ^/composer\.(json|lock) {    return 401;  }    location /vendor {    return 401;  } }

I’ve written a small WordPress Skeleton to get you started with composer.

Once you start using composer it’s really hard to go back. Give it a try — at the very least you can try installing WordPress via composer and move on from there.

Interested in working with us? See our open engineering roles here.

Stay in touch

Bringing news to you

Subscribe to our newsletter

By clicking and subscribing, you agree to our Terms of Service and Privacy Policy

Related Content

thumbnail image

AlliPMG CultureCampaigns & Client WorkCompany NewsDigital MarketingData & Technology

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

thumbnail image

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

thumbnail image

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

thumbnail image

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Testing React

13 MINUTES READ | March 12, 2019

thumbnail image

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018