Skip to content

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).

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 (such as PHP and MySQL) are pre-requisites that a system-builder must provide before installing CiviCRM.
  • A toolchain 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).


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).

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.

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 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:

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)
  • 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.

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. 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.)
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.
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:

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.


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/.

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