What is plugins.roundcube.net?

This site is the official plugin repository for Roundcube webmail. It lets you find and upload plugins and allows Composer to download and install them into your Roundcube installation.

The plugin repository is built with Packagist, an open source Composer package repository. You can find the source on GitHub.

How to submit plugins?

Naming your package

First of all, you must pick a package name. This is a very important step since it can not change, and it should be unique enough to avoid problems in the future.

The first bit of the package name must be the vendor name, suffixed by a forward slash (/). Use your github account or your personal alias here.

The secondary part of the package name is the Roundcube plugin name itself. Make sure you use the exact name of the plugin which is also the name of the folder within Roundcube's plugins/ directory.

Here is a list of typical package names for reference:

// the default archive plugin authored by the Roundcube developer

// that could be the name of an address book module for the Kolab Groupware
// (if the Kolab team did it, the vendor would be kolab)

Note that package names are case-insensitive, and it's encouraged to use a underscores (_) as separator instead of CamelCased names.

Creating a composer.json file

The composer.json file should reside at the top of your plugins's git/svn/.. repository, and is the way you describe your plugin to both the plugin repository and composer.

A typical composer.json file looks like this:

    "name": "roundcube/archive",
    "type": "roundcube-plugin",
    "description": "Archive feature for Roundcube",
    "keywords": ["mail","archive"],
    "homepage": "http://github.com/roundcube/roundcubemail",
    "license": "GPL-3.0+",
    "authors": [
            "name": "Thomas Bruederli",
            "email": "thomas@roundcube.net",
            "homepage": "http://roundcube.net",
            "role": "Developer"
    "repositories": [
            "type": "composer",
            "url": "http://plugins.roundcube.net"
    "require": {
        "php": ">=5.3.0",
        "roundcube/plugin-installer": ">=0.1.6"
    "extra": {
        "roundcube": {
            "min-version": "0.9.0",
            "max-version": "10.21"
Most of this information is obvious, keywords are tags used in the full text search, require are list of dependencies that your package has. This can of course be packages, not only a php version. You can use ext-foo to require php extensions (e.g. ext-apc). Note that most extensions don't expose version information, so unless you know for sure it does, it's safer to use "ext-apc": "*" to allow any version of it.

The complete schema description can be found in the Composer documentation.

Minimum requirements

Roundcube plugins need to have the following two properties set correctly:

    "type": "roundcube-plugin"
    "require": {
        "roundcube/plugin-installer": ">=0.1.6"

If you want to limit the Roundcube version required for your plugin (or a certain vesion of your plugin) to run, you can do this within the extra block as shown in the example above. It so happens that the internal Roundcube APIs change and therefore a newer version of your plugin might not work with an older version of Roundcube or vice versa. In this case, specifying min-version and max-version can become essential.

Once you have this file committed in your repository root, you can submit the package to the plugin repository by entering your public source repository URL.

Database initialization/upgrading

In case you plugin requires additional tables in the Roundcube database, the plugin installer can take care of their initialization when installing the plugin as well as keeping the schema up-to-date. This is done by specifying the sql-dir option in the extra/roundcube section. The value should be a relative path to a directory holding the SQL initialization and update files:

    "extra": {
        "roundcube": {
            "sql-dir": "schema/SQL"

The SQL directory should contain the schema files for initialization named with <driver>.initial.sql as well as subdirectories for each driver (e.g. mysql) holding schema update scripts named with a numeric value representing their creation date in the format 'Ymd00'. Example:


On plugin installation with a Mysql database driver configured, the file schema/SQL/mysql.initial.sql will be run against Roundcube's database connection. When the plugin is updated, all files with a name higher than the database initialization/update date from within schema/SQL/mysql/ will be executed.

Plugin install/upgrade/uninstall scripts

If the installation or upgrading of a plugin requires some additional things to be done (e.g. creating a temp folder or installing cron jobs), arbitrary shell scripts can be shipped with the plugin package and registered for execution after an install, update or uninstall operation:

    "extra": {
        "roundcube": {
            "post-install-script": "bin/install.sh",
            "post-update-script": "bin/update-me.sh",
            "post-uninstall-script": "bin/uninstall.sh"

The paths for the post-*-script options are relative to the plugin directory. Scripts can either be shell script or PHP files and will be executed with the privileges of the user who executes the plugin installation (i.e. running composer).

Control searchability and listing

In order to make your plugin appear in the search results and catalog pages, it's important to add the right keywords to it. Use the keywords property to define the terms that match your plugin. We recommend to at least add the task which you plugin mainly belongs to (e.g. mail, addressbook) there.

Managing package versions

New versions of your package are automatically fetched from tags you create in your VCS repository.

There are two ways to manage version numbering. The easiest is to just omit the version field from the composer.json file. If it is missing, the version name will be parsed from the tag and branch names. The other way which offers you a bit more flexibility is to define it yourself, but that means you should update the version field in the composer.json file before creating a tag, otherwise the tag will be considered broken and not imported. If you think you're likely to forget, you probably should use the first method.

Tag/version names should match 'X.Y.Z', or 'vX.Y.Z', with an optional suffix for RC, beta, alpha or patch versions. Here are a few examples of valid tag names:

Branches will automatically appear as "dev" versions that are easily installable by anyone that wants to try your library's latest and greatest, but that does not mean you should not tag releases. The use of Semantic Versioning is strongly encouraged.

If you specify the version manually, it will be ignored by Packagist for branches, and tags will have to contain the same version number as the tag name to be valid, so there is really no benefit to doing this.

Update Schedule

New packages will be crawled immediately after submission if you have JS enabled.

Existing packages without auto-updating (GitHub hook) will be crawled once a day for updates. When the GitHub hook is enabled packages are crawled whenever you push, or at least once a week in case the crawl failed. You can also trigger a manual update on your package page if you are logged-in as a maintainer.

It is highly recommended to set up the GitHub service hook for all your packages. This reduces the load on our side, and ensures your package is updated almost instantly. To do so you can go to your GitHub repository, click the "Admin" button, then "Service Hooks". Pick "Packagist" in the list, and add the API key you will find on your profile, plus your Packagist username if it is not the same as on GitHub. Check the "Active" box and submit the form.

The search index is updated every five minutes. It will index (or reindex) any package that has been crawled since the last time the search indexer ran.

How to write Roundcube plugins

A short introduction about how to write plugins for Roundcube can be found on our wiki. This page also contains links to the plugin API reference and the list of hooks Roundcube has implemented.

Also join our dev mailing list.