1# Repositories
2
3This chapter will explain the concept of packages and repositories, what kinds
4of repositories are available, and how they work.
5
6## Concepts
7
8Before we look at the different types of repositories that exist, we need to
9understand some of the basic concepts that Composer is built on.
10
11### Package
12
13Composer is a dependency manager. It installs packages locally. A package is
14essentially just a directory containing something. In this case it is PHP
15code, but in theory it could be anything. And it contains a package
16description which has a name and a version. The name and the version are used
17to identify the package.
18
19In fact, internally Composer sees every version as a separate package. While
20this distinction does not matter when you are using Composer, it's quite
21important when you want to change it.
22
23In addition to the name and the version, there is useful metadata. The information
24most relevant for installation is the source definition, which describes where
25to get the package contents. The package data points to the contents of the
26package. And there are two options here: dist and source.
27
28**Dist:** The dist is a packaged version of the package data. Usually a
29released version, usually a stable release.
30
31**Source:** The source is used for development. This will usually originate
32from a source code repository, such as git. You can fetch this when you want
33to modify the downloaded package.
34
35Packages can supply either of these, or even both. Depending on certain
36factors, such as user-supplied options and stability of the package, one will
37be preferred.
38
39### Repository
40
41A repository is a package source. It's a list of packages/versions. Composer
42will look in all your repositories to find the packages your project requires.
43
44By default only the Packagist repository is registered in Composer. You can
45add more repositories to your project by declaring them in `composer.json`.
46
47Repositories are only available to the root package and the repositories
48defined in your dependencies will not be loaded. Read the
49[FAQ entry](faqs/why-can't-composer-load-repositories-recursively.md) if you
50want to learn why.
51
52## Types
53
54### Composer
55
56The main repository type is the `composer` repository. It uses a single
57`packages.json` file that contains all of the package metadata.
58
59This is also the repository type that packagist uses. To reference a
60`composer` repository, just supply the path before the `packages.json` file.
61In case of packagist, that file is located at `/packages.json`, so the URL of
62the repository would be `packagist.org`. For `example.org/packages.json` the
63repository URL would be `example.org`.
64
65#### packages
66
67The only required field is `packages`. The JSON structure is as follows:
68
69```json
70{
71    "packages": {
72        "vendor/package-name": {
73            "dev-master": { @composer.json },
74            "1.0.x-dev": { @composer.json },
75            "0.0.1": { @composer.json },
76            "1.0.0": { @composer.json }
77        }
78    }
79}
80```
81
82The `@composer.json` marker would be the contents of the `composer.json` from
83that package version including as a minimum:
84
85* name
86* version
87* dist or source
88
89Here is a minimal package definition:
90
91```json
92{
93    "name": "smarty/smarty",
94    "version": "3.1.7",
95    "dist": {
96        "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
97        "type": "zip"
98    }
99}
100```
101
102It may include any of the other fields specified in the [schema](04-schema.md).
103
104#### notify-batch
105
106The `notify-batch` field allows you to specify a URL that will be called
107every time a user installs a package. The URL can be either an absolute path
108(that will use the same domain as the repository) or a fully qualified URL.
109
110An example value:
111
112```json
113{
114    "notify-batch": "/downloads/"
115}
116```
117
118For `example.org/packages.json` containing a `monolog/monolog` package, this
119would send a `POST` request to `example.org/downloads/` with following
120JSON request body:
121
122```json
123{
124    "downloads": [
125        {"name": "monolog/monolog", "version": "1.2.1.0"}
126    ]
127}
128```
129
130The version field will contain the normalized representation of the version
131number.
132
133This field is optional.
134
135#### includes
136
137For larger repositories it is possible to split the `packages.json` into
138multiple files. The `includes` field allows you to reference these additional
139files.
140
141An example:
142
143```json
144{
145    "includes": {
146        "packages-2011.json": {
147            "sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
148        },
149        "packages-2012-01.json": {
150            "sha1": "897cde726f8a3918faf27c803b336da223d400dd"
151        },
152        "packages-2012-02.json": {
153            "sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
154        }
155    }
156}
157```
158
159The SHA-1 sum of the file allows it to be cached and only re-requested if the
160hash changed.
161
162This field is optional. You probably don't need it for your own custom
163repository.
164
165#### provider-includes and providers-url
166
167For very large repositories like packagist.org using the so-called provider
168files is the preferred method. The `provider-includes` field allows you to
169list a set of files that list package names provided by this repository. The
170hash should be a sha256 of the files in this case.
171
172The `providers-url` describes how provider files are found on the server. It
173is an absolute path from the repository root.
174
175An example:
176
177```json
178{
179    "provider-includes": {
180        "providers-a.json": {
181            "sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c"
182        },
183        "providers-b.json": {
184            "sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac"
185        }
186    },
187    "providers-url": "/p/%package%$%hash%.json"
188}
189```
190
191Those files contain lists of package names and hashes to verify the file
192integrity, for example:
193
194```json
195{
196    "providers": {
197        "acme/foo": {
198            "sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82"
199        },
200        "acme/bar": {
201            "sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233"
202        }
203    }
204}
205```
206
207The file above declares that acme/foo and acme/bar can be found in this
208repository, by loading the file referenced by `providers-url`, replacing
209`%package%` by the package name and `%hash%` by the sha256 field. Those files
210themselves just contain package definitions as described [above](#packages).
211
212This field is optional. You probably don't need it for your own custom
213repository.
214
215#### stream options
216
217The `packages.json` file is loaded using a PHP stream. You can set extra options
218on that stream using the `options` parameter. You can set any valid PHP stream
219context option. See [Context options and parameters](https://php.net/manual/en/context.php)
220for more information.
221
222### VCS
223
224VCS stands for version control system. This includes versioning systems like
225git, svn, fossil or hg. Composer has a repository type for installing packages from
226these systems.
227
228#### Loading a package from a VCS repository
229
230There are a few use cases for this. The most common one is maintaining your
231own fork of a third party library. If you are using a certain library for your
232project and you decide to change something in the library, you will want your
233project to use the patched version. If the library is on GitHub (this is the
234case most of the time), you can simply fork it there and push your changes to
235your fork. After that you update the project's `composer.json`. All you have
236to do is add your fork as a repository and update the version constraint to
237point to your custom branch. Your custom branch name must be prefixed with `"dev-"`. For version constraint naming conventions see
238[Libraries](02-libraries.md) for more information.
239
240Example assuming you patched monolog to fix a bug in the `bugfix` branch:
241
242```json
243{
244    "repositories": [
245        {
246            "type": "vcs",
247            "url": "https://github.com/igorw/monolog"
248        }
249    ],
250    "require": {
251        "monolog/monolog": "dev-bugfix"
252    }
253}
254```
255
256When you run `php composer.phar update`, you should get your modified version
257of `monolog/monolog` instead of the one from packagist.
258
259Note that you should not rename the package unless you really intend to fork
260it in the long term, and completely move away from the original package.
261Composer will correctly pick your package over the original one since the
262custom repository has priority over packagist. If you want to rename the
263package, you should do so in the default (often master) branch and not in a
264feature branch, since the package name is taken from the default branch.
265
266Also note that the override will not work if you change the `name` property
267in your forked repository's `composer.json` file as this needs to match the
268original for the override to work.
269
270If other dependencies rely on the package you forked, it is possible to
271inline-alias it so that it matches a constraint that it otherwise would not.
272For more information [see the aliases article](articles/aliases.md).
273
274#### Using private repositories
275
276Exactly the same solution allows you to work with your private repositories at
277GitHub and BitBucket:
278
279```json
280{
281    "require": {
282        "vendor/my-private-repo": "dev-master"
283    },
284    "repositories": [
285        {
286            "type": "vcs",
287            "url":  "git@bitbucket.org:vendor/my-private-repo.git"
288        }
289    ]
290}
291```
292
293The only requirement is the installation of SSH keys for a git client.
294
295#### Git alternatives
296
297Git is not the only version control system supported by the VCS repository.
298The following are supported:
299
300* **Git:** [git-scm.com](https://git-scm.com)
301* **Subversion:** [subversion.apache.org](https://subversion.apache.org)
302* **Mercurial:** [mercurial.selenic.com](http://mercurial.selenic.com)
303* **Fossil**: [fossil-scm.org](https://www.fossil-scm.org/)
304
305To get packages from these systems you need to have their respective clients
306installed. That can be inconvenient. And for this reason there is special
307support for GitHub and BitBucket that use the APIs provided by these sites, to
308fetch the packages without having to install the version control system. The
309VCS repository provides `dist`s for them that fetch the packages as zips.
310
311* **GitHub:** [github.com](https://github.com) (Git)
312* **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial)
313
314The VCS driver to be used is detected automatically based on the URL. However,
315should you need to specify one for whatever reason, you can use `fossil`, `git`,
316`svn` or `hg` as the repository type instead of `vcs`.
317
318If you set the `no-api` key to `true` on a github repository it will clone the
319repository as it would with any other git repository instead of using the
320GitHub API. But unlike using the `git` driver directly, Composer will still
321attempt to use github's zip files.
322
323#### Subversion Options
324
325Since Subversion has no native concept of branches and tags, Composer assumes
326by default that code is located in `$url/trunk`, `$url/branches` and
327`$url/tags`. If your repository has a different layout you can change those
328values. For example if you used capitalized names you could configure the
329repository like this:
330
331```json
332{
333    "repositories": [
334        {
335            "type": "vcs",
336            "url": "http://svn.example.org/projectA/",
337            "trunk-path": "Trunk",
338            "branches-path": "Branches",
339            "tags-path": "Tags"
340        }
341    ]
342}
343```
344
345If you have no branches or tags directory you can disable them entirely by
346setting the `branches-path` or `tags-path` to `false`.
347
348If the package is in a sub-directory, e.g. `/trunk/foo/bar/composer.json` and
349`/tags/1.0/foo/bar/composer.json`, then you can make Composer access it by
350setting the `"package-path"` option to the sub-directory, in this example it
351would be `"package-path": "foo/bar/"`.
352
353If you have a private Subversion repository you can save credentials in the
354http-basic section of your config (See [Schema](04-schema.md)):
355
356```json
357{
358    "http-basic": {
359        "svn.example.org": {
360            "username": "username",
361            "password": "password"
362        }
363    }
364}
365```
366
367If your Subversion client is configured to store credentials by default these
368credentials will be saved for the current user and existing saved credentials
369for this server will be overwritten. To change this behavior by setting the
370`"svn-cache-credentials"` option in your repository configuration:
371
372```json
373{
374    "repositories": [
375        {
376            "type": "vcs",
377            "url": "http://svn.example.org/projectA/",
378            "svn-cache-credentials": false
379        }
380    ]
381}
382```
383
384### PEAR
385
386It is possible to install packages from any PEAR channel by using the `pear`
387repository. Composer will prefix all package names with `pear-{channelName}/` to
388avoid conflicts. All packages are also aliased with prefix `pear-{channelAlias}/`
389
390Example using `pear2.php.net`:
391
392```json
393{
394    "repositories": [
395        {
396            "type": "pear",
397            "url": "https://pear2.php.net"
398        }
399    ],
400    "require": {
401        "pear-pear2.php.net/PEAR2_Text_Markdown": "*",
402        "pear-pear2/PEAR2_HTTP_Request": "*"
403    }
404}
405```
406
407In this case the short name of the channel is `pear2`, so the
408`PEAR2_HTTP_Request` package name becomes `pear-pear2/PEAR2_HTTP_Request`.
409
410> **Note:** The `pear` repository requires doing quite a few requests per
411> package, so this may considerably slow down the installation process.
412
413#### Custom vendor alias
414
415It is possible to alias PEAR channel packages with a custom vendor name.
416
417Example:
418
419Suppose you have a private PEAR repository and wish to use Composer to
420incorporate dependencies from a VCS. Your PEAR repository contains the
421following packages:
422
423 * `BasePackage`
424 * `IntermediatePackage`, which depends on `BasePackage`
425 * `TopLevelPackage1` and `TopLevelPackage2` which both depend on `IntermediatePackage`
426
427Without a vendor alias, Composer will use the PEAR channel name as the
428vendor portion of the package name:
429
430 * `pear-pear.foobar.repo/BasePackage`
431 * `pear-pear.foobar.repo/IntermediatePackage`
432 * `pear-pear.foobar.repo/TopLevelPackage1`
433 * `pear-pear.foobar.repo/TopLevelPackage2`
434
435Suppose at a later time you wish to migrate your PEAR packages to a
436Composer repository and naming scheme, and adopt the vendor name of `foobar`.
437Projects using your PEAR packages would not see the updated packages, since
438they have a different vendor name (`foobar/IntermediatePackage` vs
439`pear-pear.foobar.repo/IntermediatePackage`).
440
441By specifying `vendor-alias` for the PEAR repository from the start, you can
442avoid this scenario and future-proof your package names.
443
444To illustrate, the following example would get the `BasePackage`,
445`TopLevelPackage1`, and `TopLevelPackage2` packages from your PEAR repository
446and `IntermediatePackage` from a Github repository:
447
448```json
449{
450    "repositories": [
451        {
452            "type": "git",
453            "url": "https://github.com/foobar/intermediate.git"
454        },
455        {
456            "type": "pear",
457            "url": "http://pear.foobar.repo",
458            "vendor-alias": "foobar"
459        }
460    ],
461    "require": {
462        "foobar/TopLevelPackage1": "*",
463        "foobar/TopLevelPackage2": "*"
464    }
465}
466```
467
468### Package
469
470If you want to use a project that does not support Composer through any of the
471means above, you still can define the package yourself by using a `package`
472repository.
473
474Basically, you define the same information that is included in the `composer`
475repository's `packages.json`, but only for a single package. Again, the
476minimum required fields are `name`, `version`, and either of `dist` or
477`source`.
478
479Here is an example for the smarty template engine:
480
481```json
482{
483    "repositories": [
484        {
485            "type": "package",
486            "package": {
487                "name": "smarty/smarty",
488                "version": "3.1.7",
489                "dist": {
490                    "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
491                    "type": "zip"
492                },
493                "source": {
494                    "url": "http://smarty-php.googlecode.com/svn/",
495                    "type": "svn",
496                    "reference": "tags/Smarty_3_1_7/distribution/"
497                },
498                "autoload": {
499                    "classmap": ["libs/"]
500                }
501            }
502        }
503    ],
504    "require": {
505        "smarty/smarty": "3.1.*"
506    }
507}
508```
509
510Typically you would leave the source part off, as you don't really need it.
511
512> **Note**: This repository type has a few limitations and should be avoided
513> whenever possible:
514>
515> - Composer will not update the package unless you change the `version` field.
516> - Composer will not update the commit references, so if you use `master` as
517>   reference you will have to delete the package to force an update, and will
518>   have to deal with an unstable lock file.
519
520## Hosting your own
521
522While you will probably want to put your packages on packagist most of the time,
523there are some use cases for hosting your own repository.
524
525* **Private company packages:** If you are part of a company that uses Composer
526  for their packages internally, you might want to keep those packages private.
527
528* **Separate ecosystem:** If you have a project which has its own ecosystem,
529  and the packages aren't really reusable by the greater PHP community, you
530  might want to keep them separate to packagist. An example of this would be
531  wordpress plugins.
532
533For hosting your own packages, a native `composer` type of repository is
534recommended, which provides the best performance.
535
536There are a few tools that can help you create a `composer` repository.
537
538### Packagist
539
540The underlying application used by packagist is open source. This means that you
541can technically install your own copy of packagist. However it is not a
542supported use case and changes will happen without caring for third parties
543using the code.
544
545Packagist is a Symfony2 application, and it is [available on
546GitHub](https://github.com/composer/packagist). It uses Composer internally and
547acts as a proxy between VCS repositories and the Composer users. It holds a list
548of all VCS packages, periodically re-crawls them, and exposes them as a Composer
549repository.
550
551### Toran Proxy
552
553[Toran Proxy](https://toranproxy.com/) is a web app much like Packagist but
554providing private package hosting as well as mirroring/proxying of GitHub and
555packagist.org. Check its homepage and the [Satis/Toran Proxy article](articles/handling-private-packages-with-satis.md)
556for more information.
557
558### Satis
559
560Satis is a static `composer` repository generator. It is a bit like an ultra-
561lightweight, static file-based version of packagist.
562
563You give it a `composer.json` containing repositories, typically VCS and
564package repository definitions. It will fetch all the packages that are
565`require`d and dump a `packages.json` that is your `composer` repository.
566
567Check [the satis GitHub repository](https://github.com/composer/satis) and
568the [Satis article](articles/handling-private-packages-with-satis.md) for more
569information.
570
571### Artifact
572
573There are some cases, when there is no ability to have one of the previously
574mentioned repository types online, even the VCS one. Typical example could be
575cross-organisation library exchange through built artifacts. Of course, most
576of the times they are private. To simplify maintenance, one can simply use a
577repository of type `artifact` with a folder containing ZIP archives of those
578private packages:
579
580```json
581{
582    "repositories": [
583        {
584            "type": "artifact",
585            "url": "path/to/directory/with/zips/"
586        }
587    ],
588    "require": {
589        "private-vendor-one/core": "15.6.2",
590        "private-vendor-two/connectivity": "*",
591        "acme-corp/parser": "10.3.5"
592    }
593}
594```
595
596Each zip artifact is just a ZIP archive with `composer.json` in root folder:
597
598```sh
599unzip -l acme-corp-parser-10.3.5.zip
600
601composer.json
602...
603```
604
605If there are two archives with different versions of a package, they are both
606imported. When an archive with a newer version is added in the artifact folder
607and you run `update`, that version will be imported as well and Composer will
608update to the latest version.
609
610### Path
611
612In addition to the artifact repository, you can use the path one, which allows
613you to depend on a local directory, either absolute or relative. This can be
614especially useful when dealing with monolithic repositories.
615
616For instance, if you have the following directory structure in your repository:
617```
618- apps
619\_ my-app
620  \_ composer.json
621- packages
622\_ my-package
623  \_ composer.json
624```
625
626Then, to add the package `my/package` as a dependency, in your `apps/my-app/composer.json`
627file, you can use the following configuration:
628
629```json
630{
631    "repositories": [
632        {
633            "type": "path",
634            "url": "../../packages/my-package"
635        }
636    ],
637    "require": {
638        "my/package": "*"
639    }
640}
641```
642
643If the package is a local VCS repository, the version may be inferred by
644the branch or tag that is currently checked out. Otherwise, the version should
645be explicitly defined in the package's `composer.json` file. If the version
646cannot be resolved by these means, it is assumed to be `dev-master`.
647
648The local package will be symlinked if possible, in which case the output in
649the console will read `Symlinked from ../../packages/my-package`. If symlinking
650is _not_ possible the package will be copied. In that case, the console will
651output `Mirrored from ../../packages/my-package`.
652
653Instead of default fallback strategy you can force to use symlink with `"symlink": true`
654or mirroring with `"symlink": false` option.
655Forcing mirroring can be useful when deploying or generating package from a monolithic repository.
656
657```json
658{
659    "repositories": [
660        {
661            "type": "path",
662            "url": "../../packages/my-package",
663            "options": {
664                "symlink": false
665            }
666        }
667    ]
668}
669```
670
671Leading tildes are expanded to the current user's home folder, and environment
672variables are parsed in both Windows and Linux/Mac notations. For example
673`~/git/mypackage` will automatically load the mypackage clone from
674`/home/<username>/git/mypackage`, equivalent to `$HOME/git/mypackage` or
675`%USERPROFILE%/git/mypackage`.
676
677> **Note:** Repository paths can also contain wildcards like ``*`` and ``?``.
678> For details, see the [PHP glob function](http://php.net/glob).
679
680## Disabling Packagist
681
682You can disable the default Packagist repository by adding this to your
683`composer.json`:
684
685```json
686{
687    "repositories": [
688        {
689            "packagist.org": false
690        }
691    ]
692}
693```
694
695&larr; [Schema](04-schema.md)  |  [Config](06-config.md) &rarr;
696