PHP Composer in WordPress Development

Composer is PHP’s dependency manager. While WordPress core doesn’t use it, you can use Composer in your own themes and plugins to manage third-party PHP libraries — without copying vendor files into version control or worrying about autoloading.

Problem: How do you manage third-party PHP libraries in a WordPress plugin or theme without manually copying vendor files into the repository or worrying about autoloading?

Solution: Add a composer.json to your plugin or theme directory, require libraries with composer require, and load the autoloader in your main PHP file with require_once __DIR__ . '/vendor/autoload.php'. Add vendor/ to .gitignore.

Initialise a composer.json for a plugin:

cd wp-content/plugins/my-plugin
composer init --no-interaction   --name="myvendor/my-plugin"   --description="My awesome plugin"   --type=wordpress-plugin

# Require a library
composer require guzzlehttp/guzzle:^7.0

# Install dev dependencies (e.g. PHPUnit, WordPress Coding Standards)
composer require --dev phpunit/phpunit:^9.0
composer require --dev wp-coding-standards/wpcs

Load Composer's autoloader in the plugin's main file:

<?php
/**
 * Plugin Name: My Plugin
 */

if ( ! defined( 'ABSPATH' ) ) exit;

// Load Composer autoloader
require_once __DIR__ . '/vendor/autoload.php';

// Now you can use any installed package
use GuzzleHttp\Client;

add_action( 'wp_loaded', function() {
    $client   = new Client();
    $response = $client->get( 'https://api.example.com/data' );
    $data     = json_decode( $response->getBody(), true );
} );

Add your own classes to Composer's autoloader using PSR-4:

{
    "autoload": {
        "psr-4": {
            "MyPlugin\": "src/"
        }
    }
}

# Regenerate the autoloader after editing composer.json
composer dump-autoload -o

Essential .gitignore additions for a Composer-based project:

/vendor/
composer.lock   # optional — include it for plugins/themes to pin exact versions

NOTE: Commit composer.lock for plugins and themes that are deployed as a unit — it guarantees every environment uses exactly the same dependency versions. Omit it from open-source libraries where users manage their own dependency resolution.