Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly.
Last updated 16 days ago by tangrufus .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install @itinerisltd/composify 
SYNC missed versions from official npm registry.


Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly.

oclif Version Downloads/week License Hire Itineris


Since plugin auothers do not ususally provide custom composer repositories (e.g: Private Packagist, satis), installing premium WordPress plugins via composer is not easy.

Lots of tutorials teach you: open composer.json and add the following within the repositories array:

// https://kinsta.com/blog/bedrock-trellis/
  "type": "package",
  "package": {
    "name": "kinsta/kinsta-mu-plugins",
    "type": "wordpress-muplugin",
    "version": "2.0.15",
    "dist": {
      "url": "https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip",
      "type": "zip"

The problems:

  • if package.dist.url is version-locked, the repositories array has to be updated whenever a new plugin version is released
  • if package.dist.url is not version-locked,$ composer install is not deterministic (even with composer.lock)
    • package.dist.url always points to the latest version
    • package.version becomes meaningless because the downloaded zip could be a newer version
    • running $ composer install (without changing anything) could break the site becuase a newer plugin version is installed
    • when composer caching invoked, there is no way to know which plugin version will be installed

The solution / what composify does:

  1. download the plugin zip file
  2. unzip it
  3. generate composer.json
  4. commit plugins files and composer.json
  5. $ git tag
  6. $ git push --follow-tags


  • NodeJS v10.0.0 or later


$ npx @itinerisltd/composify just works! No installation required.


$ npx @itinerisltd/composify --help
Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly

  $ composify

  -d, --directory=directory                       directory name after unzip [example: kinsta-mu-plugins]

  -f, --file=file                                 main plugin file which containing the plugin header comment
                                                  [example: kinsta-mu-plugins.php]

  -h, --help                                      show CLI help

  -n, --name=name                                 (required) package name [example: kinsta-mu-plugins]

  -o, --vendor=vendor                             (required) vender / organization name [example: itinerisltd]

  -r, --repo=repo                                 url to the latest zip file [example:

  -t, --type=wordpress-plugin|wordpress-muplugin  (required) [default: wordpress-plugin] package type

  -u, --unzipDir=unzipDir                         unzip file to this directory, only use when default is breking
                                                  [example: kinsta-mu-plugins]

  -v, --version                                   show CLI version

  -z, --zip=zip                                   (required) remote url or local path to the latest zip file [example:
                                                  https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip OR


Gravity Forms

$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>

Note the flags:

$ wget <the-signed-s3-url>
$ tree .
└── gravityforms_x.y.z.zip

$ unzip -o ./gravityforms_2.4.5.zip
$ tree .
├── gravityforms              <-- `--directory`
│   ├── gravityforms.php      <-- `--file`
│   ├── xxx
│   └── yyy.php
└── gravityforms_x.y.z.zip
  • --directory is omitted because it defaults to ${name}, i.e: gravityforms
  • --file is omitted because it defaults to ${name}.php, i.e: gravityforms.php
  • --repo is omitted because it defaults to https://github.com/${vendor}/${name}.git
  • --unzipDir is omitted because main plugin file is inside --directory

Advanced Custom Fields Pro

$ npx @itinerisltd/composify --vendor=itinerisltd --name=advanced-custom-fields-pro --file=acf.php --zip=https://connect.advancedcustomfields.com/xxx

Note the flags:

$ wget https://connect.advancedcustomfields.com/xxx
$ tree .
└── advanced-custom-fields-pro.zip

$ unzip -o ./advanced-custom-fields-pro.zip
$ tree .
├── advanced-custom-fields-pro        <-- `--directory`
│   ├── acf.php                       <-- `--file`
│   ├── readme.txt
│   └── xxx
└── advanced-custom-fields-pro.zip
  • --file is set to acf.php

Kinsta MU Plugins

$ npx @itinerisltd/composify --vendor=itinerisltd --name=kinsta-mu-plugins --zip=https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip --unzipSubdir --type=wordpress-muplugin

Note the flags:

$ wget https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip
$ tree .
└── kinsta-mu-plugins.zip
$ unzip -o ./kinsta-mu-plugins.zip
$ tree .
├── kinsta-mu-plugins
│   ├── xxx
│   └── yyy
├── kinsta-mu-plugins.php    <-- `--file`
└── kinsta-mu-plugins.zip
  • --unzipSubdir is set because the unzipped content is not contained inside a --directory

Auto Build


See: examples/circleci.yml

  1. Create repository on GitHub
$ mkdir example
$ cd example
$ git init

# Ensure we have a master branch
$ touch .gitkeep
$ git add .gitkeep
$ git commit -m "Add .gitkeep"
$ hub create -p itinerisltd/example
$ git push origin master
  1. Add repository to CircleCI

  2. Add environment variables to CircleCI These are minimum requirements:

Environment Variable Example Value
COMPOSIFY_REPO git@github.com:itinerisltd/example.git
COMPOSIFY_ZIP https://example.com/xxx.zip
GIT_USER_EMAIL me@example.com
  1. Add deploy keys (with write access) to both CircleCI and Github
$ ssh-keygen -t rsa -b 4096 -m PEM -C "CircleCI Composify deploy key for itinerisltd/example $(date)"
  1. Add CircleCI config
$ git checkout -b circleci
$ mkdir .circleci
$ wget https://raw.githubusercontent.com/ItinerisLtd/composify/master/examples/circleci.yml -O .circleci/config.yml

# Change SSH key fingerprint in `.circleci/config.yml`

$ git add .circleci/config.yml
$ git commit -m "Add .circleci/config.yml"
$ git push origin circleci


How to install the composify-ed plugin via composer?

Open composer.json and add your git remote into repositories:

  "repositories": [
      "type": "git",
      "url": "https://github.com/<vendor>/<name>"
$ composer require <vendor>/<name>

See: https://getcomposer.org/doc/05-repositories.md#vcs

How to composify plugin zip URLs which are password-protected?

  1. Download the zip files to your computer first
  2. $ composify/bin/run -z /path/to/the-plugin.zip -o itinerisltd -n the-plugin

Note: This is a v0.3 feature.

Can I change default flag values via environment variables?


These 2 commands are equivalent:

$ COMPOSIFY_VENDOR=itinerisltd COMPOSIFY_NAME=gravityforms COMPOSIFY_ZIP=<the-signed-s3-url> npx @itinerisltd/composify
$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>

Can I install composify instead of using $ npx?

Yes. However, you are responsible for updating it.

# yarn or npm doesn't matter
$ yarn global add @itinerisltd/composify
$ composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>

How about plugins on wordpress.org?

Use WordPress Packagist instead.

What to do when fatal: Could not read from remote repository?

ERROR: Repository not found.
fatal: Could not read from remote repository.

Make sure you have:

Is it a must to use composify with Bedrock?


Although we prefer and sponsor Bedrock at Itineris, you can composify any plugin zip files into git repositories, and install them via composer.

Bedrock alternatives:

It looks awesome. Where can I find some more goodies like this?

This isn't on wp.org. Where can I give a ⭐️⭐️⭐️⭐️⭐️ review?

Thanks! Glad you like it. It's important to make my boss know somebody is using this project. Instead of giving reviews on wp.org, consider:


Please provide feedback! We want to make this library useful in as many projects as possible. Please submit an issue and point out what you do and don't like, or fork the project and make suggestions. No issue is too small.


If you discover any security related issues, please email hello@itineris.co.uk instead of using the issue tracker.

Change log

Please see CHANGELOG for more information on what has changed recently.


composify is a Itineris Limited project created by Tang Rufus.

Full list of contributors can be found here.


composify is released under the MIT License.

Current Tags

  • 0.4.0                                ...           latest (16 days ago)
  • 0.4.0-0                                ...           next (a month ago)

7 Versions

  • 0.4.0                                ...           16 days ago
  • 0.4.0-0                                ...           a month ago
  • 0.3.1                                ...           2 months ago
  • 0.3.0                                ...           2 months ago
  • 0.2.1                                ...           3 months ago
  • 0.2.0                                ...           3 months ago
  • 0.1.0                                ...           4 months ago
Today 0
This Week 0
This Month 19
Last Day 0
Last Week 0
Last Month 21
Dependencies (8)
Dev Dependencies (9)
Dependents (0)

Copyright 2014 - 2017 © taobao.org |