CiviCRM Developer Guide


CiviCRM has an extensions framework that allows you share your custom searches, reports and payment processors with the community. Before you being work on writing an extension make sure someone else hasn't already contributed something similar by checking the list of extensions on

How to create an Extension 

Before you start, make sure your extensions are enabled! You need to configure a directory, where your extensions will be stored. To do that, you need to go to: "Administer -> Configure -> Global Settings -> Directories", fill in "CiviCRM Extensions Directory" field and click "Save" at the bottom of the page. It's best to choose a directory outside of $civicrm_root, to avoid potential problems during upgrade. Then follow the seven steps below.

1. Choose a unique key for your extension

Every extension has a unique name called the extension key. It's built using Java-like reverse domain naming to make it easier with identifying unique extensions and giving developers more flexibility on providing different extensions. So for example, if your website is and you're developing custom search showing only event payments, you can choose: as the key.

2. Create an extension directory

Go to your extensions directory and create the directory named after your key. This will be the place where you'll put all the extension related files. When you're done, it will also be put into the zip archive for further distribution.

3. Create the info.xml file

Now you need to create a file which will describe your extension so we know what a given extension does, who wrote it, who supports it and quite a few other things. It needs to be called info.xml. It's in XML format and it's relatively simple. Here's an example:

<?xml version="1.0" encoding="UTF-8" ?>
<extension key="org.civicrm.activity" type="search">
  <name>Activity Search</name>
   This custom search allows to search through activities
   and returns activities as results (not contacts as
   regular search).
  <maintainer>CiviCRM Core Team &lt;;</maintainer>
  <comments>For support, please contact project team on the forums. (</comments>

Here's a quick description of the XML elements:

  • extension - enclosing element: everything needs to sit inside of it. Attributes are:
    • key: unique name of the extension (should match the name of directory this extension resides in). We're going with Java like reverse domain naming to make it easier with identifying unique extensions and giving developers more flexibility on providing different extensions.
    • type: one of "search", "payment", "report" for now, meaning that this extension is - respectively - a custom search, payment processor or custom report.
  • callback - the name of the class that should be called in order to run this extension. Following the namespacing convention in CiviCRM, it will also be the name of the php file. Above example means that the file $extension_dir/search/ActivitySearch.php should exist and contain Extension_SearActivitySearch class. Extension_Search part of the namespace is obligatory, the rest is under extension author's control.
  • name - well, that one's easy. It's a name of the extension.
  • description - easy as well.
  • url - address to extensions website with documentation, more information, etc.
  • license - the name of the license under given extension is offered.
  • mainainer - self explanatory, hopefully. Email address inside required.
  • releaseDate - date when given extension has been released on.
  • version - version of the extension.
  • develStage - if you want to push out you extension in unstable state, here's the opportunity to be sincere about it. Allowed values are: "alpha", "beta", "stable". Beta is the default if you don't define develStage - 'cause you must have been unsure, if you forgot to provide such crucial piece of information. :-)
  • compatibilityver - lists compatible versions. It cares only about first two elements of version name and ignores the rest to avoid the need for frequent updating. So if your extension is compatible with CiviCRM 3.3, also means it supports 3.3.beta4. However, if you state it supports 3.3.beta4 (<compatibility><ver>3.3.beta4</ver></compatibility>), it won't support any other version - no go on 3.3.1.
  • comments - last one, the opportunity to say anything you want. :-)

Since we love things to be localised, we've added that too and you can provide the extension description in other languages - the optional localisedInfo section of the info file does that:

<extension ...>
    ...regular stuff
            <description>Opis po polsku.</description>
            <maintainer>Zespół CiviCRM &lt;;</maintainer>
            <comments>Wsparcie dla tego rozszerzenia dostępne na forum CiviCRM (</comments>


Please note though, this only supports name, description, maintainer and comments sections - all other extension information defined here will be ignored.  

4. Develop your extension!

Depending on the type of extension that you're building, you will need to follow different instructions. Please refer to separate chapters for:

  • Creating A Custom Search Extension
  • Creating A Report Template Extension
  • Creating A Payment Processor Extension

5. Test your extension

Make sure your extension works as planned! Once you have the info.xml file, you will be able to turn the extension on and off in the Manage CiviCRM Extensions screen - use that to see what errors you're getting and react accordingly.

6. Package your extension

Once you're done with developing and testing, you need to put all the contents of your extensions directory into a zip file. 

We'll start by creating a directory named exactly the same as the unique key that we're choosing for our extension. You need to prepare the info file as described above. Then once you have the info file, you can add the other required files and subdirectories to the extension package. This will be different for Custom Searches, Reports or Payment Processors - see each specific chapter for concrete examples. 

7. Submit your extension for public distribution

We are working on the extension submission system, but in the meantime, just get in touch with us via  with your extension or on the extensions board of the developer forum. We'll then do some testing and if everything works fine, we'll put your extension into the public distribution. Once there, everyone will be able to install it once they get to "Manage CiviCRM Extensions" screen.