Best way to install private/paid plugins with Composer?


zip is probably faster, but yeah using Git is better IMO as you just need to update the version number rather than the file URL each time.


With a .zip can you do it like this?

  "type": "vcs",
  "url": ""

Or do you have to do it like this?

        "type": "package",
        "package": {
            "name": "wp-premium/gravityforms",
            "type": "wordpress-plugin",
            "version": "",
            "dist": {
                "url": "",
                "type": "zip"


For a long time I added

    "type": "git",
    "url": ""

etc, etc, and just tagged my commits with the new version number.

Now I use Toran Proxy because you can set it up with a cron and it will mirror all your git repos and also packagist too if you want at whatever rate you decide to set the cron job for. So you really only need to push new versions to your private repos and Toran automatically stays in sync.

If you want a super ez way to do zip files check out


Hi there, if you are fed up of writing / modifying composer.json for your premium or own packages, release-belt from Rarst is a nice solution.

  1. Serve release-belt through a web server of your choice (can be the php embedded one)
  2. Drop your plugins and themes zips in release/wordpress-{plugin,theme}/company/
  3. that’s all

Relase-belt will create a composer.json automatically.

I’m just starting using it on a server on the wild with basic http auth and it works great.


I’m running into problems with this approach when deploying, as I’m not sure how to pass the --prefer-source flag to the deploy script.

Ideally, I’d like to avoid using the --prefer-source flag, but on composer update and deploy, I get the error message:

[LogicException] Downloader “Composer\Downloader\GitDownloader” is a source type downloader
and can not be used to download dist

And I really don’t understand what’s going on and how to get around it (how do you set the private plugin to be “source” rather than “dist”?).

Bedrock composer.json repository code:

      "type": "vcs",
      "url": ""

Plugin composer.json:

  "name": "growdigital/advanced-custom-fields-pro",
  "type": "wordpress-plugin",
  "source": {
    "type": "git",
    "url": "git!"

And it feels like I’ve tried every variation inbetween!!


I’ve managed to run composer with private repos locally but unfortunately I’m having the same issue when I try do deploy.yml

Loading composer repositories with package information                          
Installing dependencies from lock file                                          
  Downloader "Composer\Downloader\GitDownloader" is a source type downloader    
and can not be used to download dist                                            
install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev]        
[--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress]       
[--no-suggest] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a             
|--classmap-authoritative] [--ignore-platform-reqs] [--] [<packages>]...        
fatal: [production_host]: FAILED! => {"changed": true, "cmd": ["composer", "inst
all", "--no-ansi", "--no-dev", "--no-interaction", "--no-progress", "--optimize-
autoloader", "--no-scripts"], "delta": "0:00:00.141280", "end": "2016-11-29 05:4
9:38.212958", "failed": true, "rc": 1, "start": "2016-11-29 05:49:38.071678", "s
tderr": "Loading composer repositories with package information\nInstalling depe
ndencies from lock file\n\n                                                     
                                                              \n  [LogicExceptio
                   \n  Downloader \"Composer\\Downloader\\GitDownloader\" is a s
ource type downloader and can not be used to download dist  \n                  
                 \n\ninstall [--prefer-source] [--prefer-dist] [--dry-run] [--de
v] [--no-dev] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-pr
ogress] [--no-suggest] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--cl
assmap-authoritative] [--ignore-platform-reqs] [--] [<packages>]...", "stdout": 
"", "stdout_lines": [], "warnings": []}                                         
        to retry, use: --limit @/vagrant/deploy.retry


Got to working!

For reference, I simply removed these lines from the repo’s composer.json

"source": {
    "url": "",
    "type": "git"

And keep it like this.

    "name": "gabrielgiordan/my-plugin",
    "description": "My Plugin",
    "type": "wordpress-plugin",
    "license": "proprietary",
    "authors": [
            "name": "Gabriel Giordano"
    "require": {
		"composer/installers": "^1.0.6"

Deploy worked fine!

VirtualBox. Trellis. Ansible. Bedrock All Set. Now what

This may be of interest:


$60/m is a little steep for most freelancers. Might be a good idea for an agency though.


someone has had success with woocommerce premium plugins ?


A lot of premium ones have repos on Github too. Or set up your own for the plugins needed and use the same format as mentioned in this thread.


Thank you for reply @jasperfrumau, but if you set up for your own. You have to update every time the zip file manually. Right?


Yeah. I do this a lot for Formidable and The Events Calendar Pro. It’s a pain but there’s no other option.


DAMN! we have to find a solution :smiley:


Same here.

What I find irritating is that the composer landscape changes, frequently. I go to back to an old client site and run composer update, and it barfs cryptically about composer/installers not being up to date, which they clearly are.

Project reqs:

"composer/installers": "~1.0.12",

Plugin reqs

 "composer/installers": "v1.0"

The documentation here really needs to be brought up to date.


The documentation is on Github and the Roots team does accept pull request on them!


Quite surprised to find no mention of SatisPress in this discussion.

It’s a little rough around the edges but on the whole, a very functional solution to this tricky problem.

It runs on top of WordPress, allowing you to install premium / 3rd party plugins and setup their licenses / update mechanisms etc

The only issues we’ve found with using it so far is that the admin gets slow very quickly with that many plugins active, as many of the plugins rely on being active to check for updates etc so we’ve started splitting our plugins across multiple satispress instances (ie 1 repo for gravity forms and all add-ons, one for woo and all our premium extensions, one for general plugins like ACF).

We even use the github updater plugin to pull a bunch of our homemade plugins from git/bitbucket repos into a satispress instance, that way we don’t need a heap of different VCS repositories in our composer.json

We’ve set cron to run updates automatically, but some plugins hook in weird places that depend on having the actual wp-admin loaded, so we still try to log in and manually update the sites as needed or at least once a week

Hope this helps, it’s been the best solution my company has found so far



Hi Bish, thanks for this, will have an investigate :slight_smile:


I’m trying to get my trellis setup working with some premium plugins for wordpress. That’s really tricky. I tried to add them to the must-use-plugins (and unignored them manually in the bedrock repo). The plugin are listed in the wp backend with an appended * (what ever that means), but they aren’t really active… wp plugin list doesn’t show them.

Any idea?


You should be able to add them to the regular plugins directory; they don’t need to be “mu-plugins”. Try this first and then activate them in WordPress once they’re deployed.