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← [Schema](04-schema.md) | [Config](06-config.md) → 696