How do I release a PHP Composer package?

Composer is the standard package manager for PHP. Here’s how to release a package for it.

First let’s clarify what I’m doing. I have an example project called donut-news, and its composer.json looks like this:

    "name": "jameshfisher/donut-news",
    "description": "Donut news",
    "type": "project",
    "authors": [
            "name": "Jim Fisher",
            "email": ""
    "require": {
        "monolog/monolog": "^1.23"

The require block defines the dependencies for jameshfisher/donut-news, and currently it has one dependency: monolog, a logging library. This dependency was added by running:

php composer.phar require monolog/monolog

Now donut-news has a lot of donut logic which would be better put in a generic donuts library. I want to create a new Composer library package called donut-logic, so that I can add it to my donut-news project by running

php composer.phar require jameshfisher/donut-logic

When you run php composer.phar require foo/bar, Composer looks for the package foo/bar in repositories. A repository is a store of Composer packages. The default Composer repository is, and you can browse all the packages on here. To release jameshfisher/donut-logic, I need to get it into this list.

Composer package names are prefixed with a “vendor” name. In jameshfisher/donut-logic, the vendor is jameshfisher. On, vendor names correspond to accounts. I created an account on called jameshfisher.

Packages on are backed by git repositories. I created a new repository at

Just like your PHP projects have a composer.json, Composer packages/libraries also have a composer.json. I created this composer.json for donut-logic, and added it to the root of the repository:

    "name": "jameshfisher/donut-logic",
    "description": "Shared logic related to donuts",
    "require": {}

Next, I visited, which asks for the repository URL. I submitted it, and it registed a new package: However, this new package is not “stable”, so can’t be installed by default!:

$ php composer.phar require jameshfisher/donut-logic

  Could not find package jameshfisher/donut-logic at any version for your m
  inimum-stability (stable). Check the package spelling or your minimum-sta

It turns out that “stable” means “has a git tag”. So I tagged my current version as 0.0.1:

$ git tag 0.0.1
$ git push --tags
Total 0 (delta 0), reused 0 (delta 0)
 * [new tag]         0.0.1 -> 0.0.1

This isn’t enough, because doesn’t know that I’ve updated the source git repository. I need to tell it that the repository has been updated:

curl \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{"repository":{"url":""}}' \

(I got my API token at Now at I can see that there are two versions of my package: dev-master and 0.0.1. I can now require my package, and it gets version 0.0.1:

$ php composer.phar require jameshfisher/donut-logic
Using version ^0.0.1 for jameshfisher/donut-logic
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing jameshfisher/donut-logic (0.0.1): Downloading (100%)
Writing lock file
Generating autoload files

There’s a more reliable way to ensure that is up-to-date with the source git repo: GitHub Service Hooks. I went to, and configured it with my username and API token. Now, when my repository is updated, GitHub will notify

Tagged #php, #composer, #package-management, #programming.

Similar posts

More by Jim

👋 I'm Jim, a full-stack product engineer. Want to build an amazing product and a profitable business? Read more about me or Get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.