Composer: Part 1 – What & Why

You may have heard about Composer and Packagist lately. In short, Composer is a new package manager for PHP libraries. Quite a few people have been complaining about the lack of information, or just seemed confused as to what it was, or why the hell we would do such a thing. This is my attempt at clarifying things.

This second part of this post, Impact, has now been published.

What is it?

The Composer ecosystem is made of two main parts, both are available on GitHub. The development effort is being led by Nils Adermann and myself (Jordi Boggiano), but we already have more than 20 contributors which I would like to thank a bunch for helping.

Composer

Composer is the command-line utility with which you install packages. Many features and concepts are inspired by npm and Bundler, so you may recognize things here and there if you are familiar with those tools. It contains a dependency solver to be able to recursively resolve inter-package dependencies, a set of downloaders, installers and other fancy things.

Ultimately as a user, all you have to do is drop a composer.json file in your project and run composer.phar install. This composer.json file defines your project dependencies, and optionally configures composer (more on that later). Here is a minimal example to require one library:

{
    "require": {
        "monolog/monolog": "1.0.0"
    }
}

If we look at the package publisher side, you can see that there is some more metadata you can add to your package. This is basically to allow Packagist to show more useful information. One thing that is great though is that if your library follows the PSR-0 standard for class and files naming, you can declare it here (see the last two lines below) and Composer will generate an autoloader for the user that can load all of his project dependencies.

{
    "name": "monolog/monolog",
    "description": "Logging for PHP 5.3",
    "keywords": ["log","logging"],
    "homepage": "http://github.com/Seldaek/monolog",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Jordi Boggiano",
            "email": "j.boggiano@seld.be",
            "homepage": "http://seld.be"
        }
    ],
    "require": {
        "php": ">=5.3.0"
    },
    "autoload": {
        "psr-0": {"Monolog": "src/"}
    }
}

Composer is distributed as a phar file. While that usually works out, if you can’t even get it to print a help with php composer.phar, you can refer to the Silex docs on pitfalls of phar files for steps you can take to make sure your PHP is configured properly.

Packagist

Packagist is the default package repository. You can submit your packages to it, and it will build new packages automatically whenever you create a tag or update a branch in your VCS repository. At the moment this is the only supported way to publish packages to it, but eventually we will allow you to upload package archives directly, if you fancy boring manual labor. You may have noticed in the composer.json above that there was no version, and that is because Packagist takes care of it, it creates (and updates) a master-dev version for my GitHub repo’s master branch, and then creates new versions whenever I tag.

You can run your own copy of Packagist if you like, but it is built for a large amount of packages, so we will soon release a smaller tool to generate repositories that should be easier to setup for small scale repositories.

If you have no interest in using Packagist with Composer, or want to add additional repositories, it is of course possible.

Why(s)?

Why do I need a package manager?

There is a huge trend of reinventing the wheel over and over in the PHP world. The lack of a package manager means that every library author has an incentive not to use any other library, otherwise users end up in dependency hell when they want to install it. A package manager solves that since users do not have to care anymore about what your library depends on, all they need to know is they want to use your stuff. Please think about it real hard, let it sink, I will get back to that in the next post.

So we started working on Composer because there is no satisfactory solution at the moment for PHP, and that is quite unacceptable in this day and age. Of course with such a bold statement, you may be wondering:

Why not use PEAR?

While PEAR was and remains a viable option to some people, many have also been dissatisfied with it for various reasons. Composer has a very different philosophy, and it probably will not please everybody either. The main aspect that differs is that PEAR started as a system-wide package manager, much like apt-get or other similar solutions.

That approach does not work very well when you have many projects running on one machine, some of them 5 years old and depending on outdated versions of a library a newer project also uses. You can’t easily install both versions at the same time, and lots of frustration ensues.

Another issue is that one project’s dependencies become very fuzzy, since you code against code that is installed somewhere on your system, you can easily forget to mention in your README that your app depends on library X. Future-you or another guy comes along, tries to setup the project and is left in a run -> see error -> install lib -> run loop until all errors are gone. If he is really out of luck, he misses one dependency that is rarely used, and something fails unnoticed later on.

Composer on the other hand forces you to declare your project dependencies in a one-stop location (composer.json at the root). You just checkout the code, install dependencies, and they will sit in the project directory, not disturbing anything else on the machine. Another related feature is the composer.lock file that is generated when you install or update dependencies. It stores the exact version of every dependency that was used. If you commit it, anyone checking out the project will be able to install exactly the same versions as you did when you last updated that file, avoiding issues because of minor incompatibilities or regressions in different versions of a dependency. If you ever had bugs appear only on one team member’s machine while the others were fine because of some too-new or too-old version of something, you will know this is very useful.

Another notable difference, although some may not care about this, is that there is no approval process to have your package included on Packagist. While our vendor-name/package-name convention resembles PEAR’s channel/package, we do not have channels. All repositories contain packages that go into one big package pool, and then the solver figures out which packages fit your requirements, no matter where they come from.

Why JSON for packages?

It is a recurring question so I will answer it, hopefully for the last time. The short answer is because. The longer one is that there are many options (yaml, json, xml, php, ini, whatever.), each have their fan-base, and each have their haters. Whatever we would have picked, someone would be complaining. If you think it is a stupid decision, I am sorry to announce you are in the group selected to be the folks complaining, but it is not going to change. Please try not to focus on such a detail, and look at the bigger picture.

Where are we now?

I have delayed writing this post for quite a long time. I wanted it to be all nice and shiny before announcing anything. Unfortunately it is not as polished as I would like yet, but we are getting there. Composer can install itself (well, its dependencies) via Packagist, and many people have played with it and looking to integrate it in their work environments.

Here are the main points that still need some love, and of course if you would like to help you can join us on IRC (freenode #composer-dev) or on the mailing list.

Documentation

Documentation – or the lack thereof – is a huge problem right now. This post is a first step in that direction, and we will definitely work on more formal documentation in the future. You could too.

Solver bugs

The dependency solver is a complex beast, it has been ported from C code and it still has some rough edges. Not much to say here, we just need people to try it and report bugs. Bonus points if you can write a unit test that reproduces the issue.

Private repositories

This is a big topic that we need to address as well. Installing closed-source packages is of course necessary in most companies, and we will definitely work on it once the basics are working well and the open-source use case is covered. If you have some time or money to invest in that and want it to happen ASAP, please get in touch with us.

Global installs

As I said, we work with local installs by default, and that will not change for everything that is directly project-related. That being said, there is a whole set of CLI-tools for testing/QA or other purposes that would benefit from being installed system-wide and executable from anywhere. It is already possible to do a local install of those in your home dir and then add the bin directory of that install to your PATH of course, but we would like to support a more streamlined experience.

Part two will come next week, covering a few use cases, visions and hopes we have for Composer and PHP as a whole. To stay up to date you can follow @packagist or myself on twitter.

Update: You can now read Part2

December 8, 2011 by Jordi Boggiano in Development // Tags: , 48 Comments

48 Responses to Composer: Part 1 – What & Why

  1. Lukas says:

    First up slap Nils as he promised to create a subtree split repo of the resolver: https://github.com/composer/composer/tree/master/src/Composer/DependencyResolver

    Know make it easy for others to adopt this code to get bugs fixed.

    Second, I don’t think it makes sense to really work on system-wide installs. For that use case OS specific packages (.deb, RPM etc.) make way more sense.

  2. Regarding system-wide installs, “.deb, RPM etc.” do not cover Windows, and not everyone developing such a tool wants to spend time doing packaging. Distro packagers will surely provide packages for most popular tools, but what about newcomers and fringe stuff? I think it should still be easy to install and use them. That being said it is indeed not a top priority, we need docs and a few other things first.

  3. Daniel Tiecher says:

    Totally agree with Jordi regarding the need of global installs.

    The main points that should be adressed for me right now are Documentation and improvements on the Packagist website.

    Right now it’s (the site) lacking any kind of sane way to browse packages (search, popularity, etc). This is a deal breaker for a lot of newbie users that would benefit from such a system.

  4. Pingback: Nelm.io Blog: Komponist: Teil 1 – Was & Warum | PHP Boutique

  5. Alex T says:

    It would be neat if something like this supported adding installed bundles’ namespaces to the autoload and automatically registered bundles.

    Then to add a dependency to a project, someone would only need to add it to their list. Way less time spent in dependency hell.

  6. @Daniel: Igor has been working on search, it should be available soon.

    @Alex: Autoloading is already handled, and for Symfony2 specifically, adding bundles to the AppKernel should be doable, it’s definitely planned.

  7. Pingback: Compilado de enlaces « programacion@droope

  8. Alex T says:

    Good show! That pretty much has me sold on it. Especially if packages can indicate that they have to come from github!

    It would certainly go a long way to helping get many of the different non-core Symfony bundles out there used.

    Daniel’s point is valid. Composer would be useful as a back-end for something like asp.NET’s NuGet.

  9. Obsidian says:

    Worth noting that for the point of “Why JSON?”, it’s also probably (partially, at least) because Composer is written in PHP and as we all (as of 5.2) have json_encode/json_decode in the core, we all don’t have to rely on overcomplicated/inefficient parser code (such as SimpleXML, or YAML parsing). Means less external dependencies for a dependency management library.

    Anyways, regarding that issue I’d been participating in with OpenSSL-signed phars being distributed, I’ll probably pop on IRC some time in the next week. Right now unfortunately, I’m stuck in finals /hell/.

  10. Adrian says:

    Awesome. Thank you Jordi and Nils so much! I’ve been thinking about PHP needing a good package manager for a while now.

    It would be nice to distribute composer by usual os package manager. So people can install composer by something like “apt-get install php-composer” for example. This way composer itself can be kept updated to the latest version.

    Hopefully composer will spread a lot in the PHP community and become a standard for project dependencies.

  11. @Adrian: I’m sure this will come in time, but for now you can easily get the phar file from getcomposer.org and then there is a “composer.phar self-update” command that replaces it with the latest, so the process isn’t so complicated.

  12. b00gizm says:

    Thanks for your work :) We’re currently working on migrating our latest projects to use Composer. One question though:

    Suppose I have a dependency which follows the PSR-0 standard but hasn’t declared it yet in its composer.json. Where (in my composer.json) do I have to declare it if I want to enable autoloading?

    • From your application’s composer.json if you want to declare autoload rules for a dependency, you can use the following hack:

      1
      2
      3
      4
      5
      6
      7
      8
      {
          "autoload": {
              "psr-0": {
                  "Dependency\\Namespace": "vendor/your/dependency/src/",
                  "Your\\Namespace": "src/"
              }
          }
      }

      The best thing to do though is to nag people to fix their composer.json. And if they don’t support composer at all, you can nag them as well, but in the meantime you can use inline package definitions, see http://packagist.org/about-composer (search for “Adding code that does not support composer”).

  13. Pingback: Composer: Part 2 – Impact | Nelmio Blog

  14. ryeguy says:

    How does it handle dependency conflicts? Let’s say your project depends on Foo v2.0 and Bar v2.0. But Bar v2.0 itself relies on Foo v1.0. So now you have 2 different versions of the same library that are needed in your application.

  15. Pingback: Composer: Part 2 – Impact - Nelmio - Atualités

  16. Pingback: Andho » Talking about Composer, a package manager for PHP

  17. mario says:

    Complainee here. The JSON is a big step up from PEARs fugly XML. But babysitting another syntax doesn’t look like a timesaver to me. If you reimplement something because you don’t want to follow any actual standard (PKG-INFO or debian/control) or can’t be bothered to implement a regex two-liner for “parsing”, then, well I don’t know – how well though out could the rest of the code possibly be? I suspect you will keep hearing about it, simply because requiring extra work due to the main interface doesn’t resonate well for tools that should simplify tasks.

    Due to the manual, I haven’t yet understood the use case completely. But I kind of get the impression this might be another kludge for the namespace directorities, and the PSR-0 pseudo standard. (No, just because a couple of framework fairies decided something on a then closed mailing list [and intentionally or due to unwareness bork language semantics] doesn’t make it an actual “standard”. Not by any stretch.)

    Anyway it still sounds useful for many projects and deployment settings. It just needs detail. More.

    • Regarding PSR-0, the spec actually allows Foo\Bar_Baz => Foo/Bar/Baz.php transformations. Which would allow all classes from a package to live in the same namespace, hopefully reuniting with your vision of the language semantics. If that’s not what you meant though, then maybe you should do more explaining and less ranting.

      That being said, most (all?) implementors adopted Fully\Name\Spaced names, with the ensuing use fest.

  18. Obsidian says:

    Considering how PSR-0′s quite contested, how well are other autoloading types supported? Is literal autoloading supported?

    ref: literal autoloading’s just like the implementation defined on php.net when namespacing was introduced – just replacing the namespace separator with a directory separator, and using the rest of the class/namespace path literally when performing the include, like with: http://us3.php.net/manual/en/function.spl-autoload-extensions.php

  19. Adrian says:

    I’d like to use homebrew on OS X to install composer.phar but the MD5 checksum of http://getcomposer.org/composer.phar changes every now and then.

    Is there a download link for composer.phar for a specific version which won’t change? I’m looking for something like: http://getcomposer.org/composer-xyz.phar

    • Did you look at the instructions in our README? I think they contain a workaround for the hash issue. That said I know only little about homebrew, but regarding fixed versions, we will have them once it is more stable and we actually do releases.

  20. Pingback: Externe Bibliotheken in PHP laden: Composer und Packagist - blog.ch

  21. Pingback: Four Days at jsDay / PhpDay italian conference | Apps Comments

  22. Pingback: Four Days at jsDay / PhpDay conference | Apps Comments

  23. Pingback: Nelmio is hiring | Nelmio Blog

  24. Pingback: Composer - Dependency Manager for PHP

  25. Pingback: My answer to People asking whether they should or not use a framework on their programming language | Renoir Boulanger Un geek social et Linuxien de nature

  26. shwetanka srivastava says:

    I totally hate composer!! Symfony is better without it!

  27. Pingback: Handle your dependencies with PHP composer | fortrabbit – Blog

  28. Pingback: Managing your PHP dependencies with Composer - Build and Pray

  29. Pingback: Instalando o pacote Composer no Windows | LPDeveloper

  30. Pingback: Enkel pakethantering med Composer | Fosseus.se

  31. I’ve just started using Composer, thank you very much for finally rescuing me!

  32. Ludo says:

    I juste discovered it when updating to Symfony 2.1. This is would be a must-have for all my php projets :)

  33. Qrious says:

    First of all, I would like to say that Composer actually is a great tool and it is definitely a great step forward. However there is one problem in my opinion: It requires commandline access…(no I am not afraid of the commandline, please continue reading :P)

    In your next post you mention that you would like to see Composer implemented in WordPress for example. I don think this is likely to happen because most WordPress sites are hosted on shared hosting (no source, just my experience). Some of them support commandline access, and some do not. The same applies to PHAR support.

    Since the majority of the PHP driven websites are hosted on shared hosting (again no source), we should really consider making Composer (lite?) compatible with those hosts. Of course there is a limit on what Composer can support, it needs at least allow_url_fopen or CURL etc. If Composer would be available for shared hosting, then it would definitely become the standard.

    I had a short look at Composer source code, and I saw a few things that would explain why it needs the commandline (or a tweakable PHP installation), like the memory limit. However would it be possible to create a version that works on (most) shared hosting plans? Or are there some serious problems involved?

    • Actually it doesn’t really have so many things that tie it to the command line. In the end it is just a library that has a command line wrapper in a phar file.

      Using it with a GUI is possible already, you just probably can not rely on git being there and the memory limit might indeed be an issue on very restrictive shared hosts.

  34. Camilo says:

    This is the problem with the open source community, so much cool stuff being done but no documentation, no way to find out how to use it or where to put it, yes, most of you are seasoned programmers but some of us aren’t and when someone tells me you have to install Composer so your code works it pissed me off. At some point everything turns into an obscure code that no one can actually use. People should stop publishing code without the proper documentation!!! STOP IT!

    • Mike says:

      Agreed. People talk about Test Driven Development, however it should be Documentation AND Test Driven Development.

      However I think it’s great these guys are putting in the effort.

  35. Pingback: 【转】2011年最热门的开源PHP项目回顾 | 浪淘沙

  36. Pingback: Behat 2.2: Bunch of new features | KNP Blog

  37. Pingback: Does PHP have like ruby gem bundler? - PHP Solutions - Developers Q & A

  38. Pingback: PHP Package Manager – 從 PEAR 到 Composer – Tiger-Workshop Blog

  39. Pingback: Programowanie w PHP » Blog Archive » Nelm.io Blog: Composer: Part 1 – What & Why

  40. Hey! I’m at work surfing around your blog from my new apple iphone! Just wanted to say I love reading your blog and look forward to all your posts! Keep up the outstanding work!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>