Home > Developer Guide > Core
Core Dependencies (Libraries)
The core dependencies are the software libraries loaded by civicrm-core
(and distributed alongside
civicrm-core
). These include server-side PHP libraries (such as Symfony Dispatcher) and client-side libraries (such
as jQuery).
Core dependencies are organized in two areas: the newer composer.json
(preferred) and the older
civicrm-packages.git
(deprecated).
??? question "How do the Core Dependencies differ from the Installation Requirements or the Toolchain?"
The words "dependency" and "requirement" are similar, but the following are technically distinct areas:
* The _core dependencies_ (such as jQuery and Symfony Dispatcher) are libraries that must be loaded by CiviCRM at runtime.
* The [_installation requirements_](https://docs.civicrm.org/installation/en/latest/general/requirements/) (such as PHP and MySQL) are pre-requisites that a system-builder must provide before installing CiviCRM.
* A [_toolchain_](../tools/buildkit.md) is a set of add-on tools (such as `drush` and `phpunit`) used to build the software. These are important for system-builders
and developers, but they are not loaded by CiviCRM at runtime.
This page focuses on the core dependencies (libraries).
Principles
??? info "Core dependencies must have broad compatibility..."
They should work with all supported PHP versions and all UF's/CMS's (Drupal 7/8/9/10, WordPress,
Backdrop, Joomla, Standalone).
??? info "Core dependencies may (or may not) be systemically important..."
* __Example 1__: Symfony Dispatcher defines the `EventSubscriberInterface` which appears in CiviCRM developer documentation and downstream
extensions. Changes to Symfony Dispatcher could affect downstream compatibility, so they should be reviewed carefully. This is
systemically important.
* __Example 2__: `marcj/topsort` is only used internally. CiviCRM could update this library without any downstream impact.
This must be assessed on a case-by-case basis.
??? info "Patches to core dependencies should be minimized..."
It is _possible_ to apply our own patches on top of core dependencies (without upstream review). The wisdom of doing
so depends on the severity of the issue and the health of the upstream project.
In general, if upstream is active, then patches should be reviewed, revised, and released in their upstream's workflow.
However, if a patch is critical to compatibility or security, or if upstream is not maintained, then CiviCRM may
apply its own patch (until the issue is resolved upstream).
Composer.json
composer
is the primary tool for managing CiviCRM's core dependencies. It is popular for PHP-based projects, and
you'll find ample resources online (such as official documentation and unofficial
discussions).
For civicrm-core
, there are some additional tips and guidelines for how to approach composer
:
??? info "Composer handles PHP libraries... and also JS/CSS libraries..."
As you may expect, `composer` downloads PHP libraries. In `composer.json`, these appear in the usual section (`"require":...`).
What you may not expect: it also handles JS/CSS libraries. By convention:
* JS/CSS dependencies are declared in `composer.json` underneath `"extra": {"download":{...}}`.
(See also: [civicrm/composer-downloads-plugin](https://github.com/civicrm/composer-downloads-plugin))
* JS/CSS dependencies are downloaded into the folder `bower_components/`.
Historically (circa v4.6), the JS/CSS libraries were downloaded via `node`/`bower`. It was subsequently simplified (circa v5.17) to use a
lighter and more maintainable toolchain. The folder-name was preserved within 5.x for interoperability.
??? info "Composer applies patches for third-party libraries..."
Core dependencies sometimes require patches for compatibility or security. When necessary, these patches
are applied via [cweagans/composer-patches](https://github.com/cweagans/composer-patches/). These patches
are declared `composer.json` under `"extra":{"patches":{...}}`
Patches must be identified with an absolute URL. This ensures compatibility with all environments, including
D7-style (*civicrm as main project*) and D8-style (*civicrm as subordinate project*).
Patch URLs should identify immutable content (with some version#, checksum, or UUID). This ensures that
consistency in tests/releases/quality-control.
Here are a few ways to make a suitable URL:
1. Paste the patch into a gist. Use the URL of the raw gist. Or...,
2. Send a PR upstream. Get it approved. Use the URL of the PR-diff. Or...,
3. Get a link to a historical patch-file that was previously bundled into civicrm-core.git. (Not applicable to new patches.)
??? info "CiviCRM might be the main composer project (D7/WP/BD/J)..."
In Drupal 7, WordPress, Backdrop, and Joomla, site-builders do not traditionally run `composer` themselves.
For these environments, `civicrm-core` has its own `composer` project. This means:
* CiviCRM has complete and final discretion in how dependencies are resolved.
* The `composer.lock` from `civicrm-core` is authoritative.
* All options in `composer.json` (such as post-install scripts) are fully respected.
??? info "CiviCRM might be a subordinate composer project (D8/D9/D10)..."
In Drupal 8 (and newer), site-builders typically run `composer` themselves. There is a pre-existing project, and
CiviCRM is usually added into this project:
```bash
cd /var/www/my-drupal-site
composer require civicrm/civicrm-core ...
```
For these environments, `civicrm-core` is subordinate:
* The site-builder has final discretion in how dependencies are resolved.
* The `composer.lock` from `civicrm-core` is ignored.
* Some options in `composer.json` (such as post-install scripts) are ignored.
CiviCRM-Packages
Since CiviCRM v1.x, the packages/
folder has stored a collection of manually curated dependencies. The folder
corresponds to a git repository (civicrm-packages.git
).
Adding new code to packages/
is generally deprecated, and many dependencies have switched to composer.json
.
However, some important dependencies are still tracked in packages/
.
??? question "Why would a dependency still reside in civicrm-packages
?"
Each package may be different. Here are a few possible reasons:
1. Nobody has gotten around to converting it.
2. The dependency is no longer maintained by upstream. It is easier to do security and compatibility updates in this repo.
3. The dependency requires special loading rules or special conditions.
4. The dependency's file-path is important. Moving it requires coordination with other repositories/subsystems.
For more information about managing the packages/
folder, see civicrm-packages.git:VERSIONS