PHPackages                             sweetchuck/composer-suite - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sweetchuck/composer-suite

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

sweetchuck/composer-suite
=========================

Generates multiple variations of the original composer.json

v1.4.0(1y ago)26.0k[1 issues](https://github.com/Sweetchuck/composer-suite/issues)6GPL-3.0-or-laterPHPPHP &gt;=7.4

Since Jan 17Pushed 5mo ago2 watchersCompare

[ Source](https://github.com/Sweetchuck/composer-suite)[ Packagist](https://packagist.org/packages/sweetchuck/composer-suite)[ Docs](https://github.com/Sweetchuck/composer-suite)[ RSS](/packages/sweetchuck-composer-suite/feed)WikiDiscussions 2.x Synced 3w ago

READMEChangelog (5)Dependencies (18)Versions (9)Used By (6)

Composer Suites
===============

[](#composer-suites)

[![CircleCI](https://camo.githubusercontent.com/7d3d5b622d1a19acf2d812bfcbdf0e726aaa912ae9e9dbf9e56dd1292dd24bdf/68747470733a2f2f636972636c6563692e636f6d2f67682f5377656574636875636b2f636f6d706f7365722d73756974652f747265652f322e782e7376673f7374796c653d737667)](https://circleci.com/gh/Sweetchuck/composer-suite/?branch=2.x)[![codecov](https://camo.githubusercontent.com/3095c4a519cf28a3698bd25ca47cd1e8875a4625efc33c22a38e2083f7bc3ef7/68747470733a2f2f636f6465636f762e696f2f67682f5377656574636875636b2f636f6d706f7365722d73756974652f6272616e63682f322e782f67726170682f62616467652e7376673f746f6b656e3d4f586c46557668364159)](https://app.codecov.io/gh/Sweetchuck/composer-suite/branch/2.x)

Generates multiple variations of the original `composer.json`

1. You have to define the differences in the composer.json#/extra/composer-suite, see the examples below.
2. Next step is to generate the alternative composer.json files by running the following command:
    `composer -vv suite:generate`
3. Activate one of the alternative composer.json file by setting the [COMPOSER environment variable](https://getcomposer.org/doc/03-cli.md#composer).
    1. `export COMPOSER='composer.my-suite-01.json'`
    2. `composer update --lock`

Other benefit is that, if there is any relative path in the `composer.json` – for example under the `#/repositories/FOO/url` or anywhere under the `#/extra` – then those paths will work with the alternative composer.\*.json files as well.

Example composer.json - multi-version dependency
------------------------------------------------

[](#example-composerjson---multi-version-dependency)

```
{
    "require": {
        "symfony/console": "^4.0 || ^5.0",
        "symfony/process": "^4.0 || ^5.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {
        "composer-suite": {
            "symfony4": {
                "description": "Make sure Symfony 4.x will be used.",
                "actions": [
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "items": {
                                "require": {
                                    "symfony/console": "^4.0",
                                    "symfony/process": "^4.0"
                                }
                            }
                        }
                    }
                ]
            },
            "symfony5": {
                "description": "Make sure Symfony 5.x will be used.",
                "actions": [
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "items": {
                                "require": {
                                    "symfony/console": "^5.0",
                                    "symfony/process": "^5.0"
                                }
                            }
                        }
                    }
                ]
            }
        }
    }
}
```

Run: `composer suite:generate`
The generated files:
**composer.symfony4.json**

```
{
    "require": {
        "symfony/console": "^4.0",
        "symfony/process": "^4.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {}
}
```

**composer.symfony5.json**

```
{
    "require": {
        "symfony/console": "^5.0",
        "symfony/process": "^5.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {}
}
```

**Then**

```
unset COMPOSER
composer update --lock
composer suite:generate

export COMPOSER='composer.symfony4.json'
composer update
composer run test

export COMPOSER='composer.symfony5.json'
composer update
composer run test

# Back to normal.
unset COMPOSER
composer update --lock
```

Example composer.json - local development
-----------------------------------------

[](#example-composerjson---local-development)

**Use case**

A certain third-party service has to be integrated into a framework.

Composer packages:

- RestAPI client (type: library)
- module/plugin for the framework (type: library)
- the framework (type: project)

```
{
    "type": "project",
    "repositories": {},
    "require": {
        "my/module_01": "^1.0"
    },
    "require-dev": {
        "sweetchuck/composer-suite": "^1.0"
    },
    "extra": {
        "composer-suite": {
            "local": {
                "description": "Local development",
                "actions": [
                    {
                        "type": "prepend",
                        "config": {
                            "parents": ["repositories"],
                            "items": {
                                "my/module_01": {
                                    "type": "path",
                                    "url": "../../my/module_01-1.x",
                                    "options": {
                                        "repo-path": {
                                            "url": "https://github.com/my/module_01.git",
                                            "branch": "1.x"
                                        }
                                    }
                                },
                                "my/restapi_client_01": {
                                    "type": "path",
                                    "url": "../../my/restapi_client_01-1.x",
                                    "options": {
                                        "repo-path": {
                                            "url": "https://github.com/my/restapi_client_01.git",
                                            "branch": "1.x"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "parents": ["require"],
                            "items": {
                                "my/module_01": "1.x-dev",
                                "my/restapi_client_01": "1.x-dev"
                            }
                        }
                    }
                ]
            }
        }
    }
}
```

Run: `composer suite:generate`
The generated file:
**composer.local.json**

```
{
    "type": "project",
    "repositories": {
        "my/module_01": {
            "type": "path",
            "url": "../../my/module_01-1.x",
            "options": {
                "repo-path": {
                    "url": "https://github.com/my/module_01.git",
                    "branch": "1.x"
                }
            }
        },
        "my/restapi_client_01": {
            "type": "path",
            "url": "../../my/restapi_client_01-1.x",
            "options": {
                "repo-path": {
                    "url": "https://github.com/my/restapi_client_01.git",
                    "branch": "1.x"
                }
            }
        }
    },
    "require": {
        "my/module_01": "1.x-dev",
        "my/restapi_client_01": "1.x-dev"
    },
    "require-dev": {
        "sweetchuck/composer-suite": "^1.0"
    },
    "extra": {}
}
```

**Then**

```
unset COMPOSER
composer update --lock
composer suite:generate

cp ./composer.lock ./composer.local.lock
export COMPOSER='composer.local.json'
composer update --lock

# You can work on both libraries (restapi_client_01 and module_01) on-the-fly.

# Back to normal.
unset COMPOSER
composer update --lock
```

Suites
------

[](#suites)

You can have as many suites as many you want.

As the examples above show that, suites can be defined in the `composer.json#/extra/composer-suite`, but suite definitions can be stored in external files as well.
`./.composer-suite/composer-suite.*.json`. Then it is up to you if these files will be tracked by the VCS or not.

**Example `./.composer-suite/composer-suite.foo.json`:**

```
{
    "name": "foo",
    "description": "My foo suite.",
    "actions": []
}
```

The `name` key is optional. If it is omitted then, the suite name will be parsed from the file name.

If two suites have the same name, then the one which comes from external file, has the highest priority.

Actions
-------

[](#actions)

You can define different array manipulation actions under the `extra/composer-suite/` keys.

An action has two main properties:

- type (string) Identifier of the action.
- config (mixed) The data type is usually array, but it depends on the `type`.

### Action - replaceRecursive

[](#action---replacerecursive)

Official PHP documentation: [array\_replace\_recursive()](https://php.net/manual/en/function.array-replace-recursive.php)

- parents: array
- items: array

```
{
    "require": {
        "a/b": "^1.0",
        "symfony/console": "^4.0",
        "symfony/process": "^4.0"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": " replaceRecursive",
                    "config": {
                        "parents": [],
                        "items": {
                            "require": {
                                "symfony/console": "^5.0",
                                "symfony/process": "^5.0"
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Result:

```
{
    "require": {
        "a/b": "^1.0",
        "symfony/console": "^5.0",
        "symfony/process": "^5.0"
    },
    "extra": {}
}
```

### Action - unset

[](#action---unset)

Removes the specified elements.

- parents: array

```
{
    "name": "a/b",
    "foo": {
        "bar": "delete me"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": "unset",
                    "config": {
                        "parents": [
                            "foo",
                            "bar"
                        ]
                    }
                }
            }
        }
    }
}
```

Result:

```
{
    "name": "a/b",
    "foo": {},
    "extra": {}
}
```

In the "config.parents" array the last item can be an array:

```
{
    "name": "a/b",
    "foo": {
        "a": "delete me 1",
        "b": "keep me",
        "c": "delete me 2"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": "unset",
                    "config": {
                        "parents": [
                            "foo",
                            [
                                "a",
                                "c"
                            ]
                        ]
                    }
                }
            }
        }
    }
}
```

Result:

```
{
    "name": "a/b",
    "foo": {
        "b": "keep me"
    },
    "extra": {}
}
```

### Action - prepend

[](#action---prepend)

Adds new elements at the beginning of an array.

- parents: array
- items: array

```
{
    "repositories": {
        "old/p1": {}
    },
    "extra": {
        "composer-suite": {
            "local": {
                "actions": [
                    {
                        "type": "prepend",
                        "config": {
                            "parents": [
                                "repositories"
                            ],
                            "items": {
                                "new/p1": {},
                                "new/p2": {}
                            }
                        }
                    }
                ]
            }
        }
    }
}
```

Result:

```
{
    "repositories": {
        "new/p1": {},
        "new/p2": {},
        "old/p1": {}
    },
    "extra": {}
}
```

### Action - append

[](#action---append)

Adds new elements at the end of an array.

- parents: array
- items: array

### Action - insertBefore

[](#action---insertbefore)

Insert one or more "items". The last item in the "parents" is the reference point.

- parents: array
- items: array

### Action - insertAfter

[](#action---insertafter)

Insert one or more "items". The last item in the "parents" is the reference point.

- parents: array
- items: array

Commands
--------

[](#commands)

This Composer plugin defines the following commands:

- `composer suite:list`
- `composer suite:generate`

Validate
--------

[](#validate)

You can check the status of the autogenerated files by running the official `COMPOSER='composer.json' composer validate` command.
If one of the autogenerated file **is exists AND out-of-date**, then the exit code will be other than `0`.
This command does not report any problem about the missing composer.\*.json files.

Links
-----

[](#links)

1. [COMPOSER environment variable](https://getcomposer.org/doc/03-cli.md#composer)

Other
-----

[](#other)

1. `"$(composer config bin-dir)/codecept" _completion --generate-hook --program codecept | source /dev/stdin`

---

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance45

Moderate activity, may be stable

Popularity24

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~230 days

Recently: every ~337 days

Total

9

Last Release

152d ago

Major Versions

v1.4.0 → 2.x-dev2026-01-31

PHP version history (2 changes)v1.0.0PHP &gt;=7.4

2.x-devPHP &gt;=8.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/591103?v=4)[Andor](/maintainers/Sweetchuck)[@Sweetchuck](https://github.com/Sweetchuck)

---

Top Contributors

[![Sweetchuck](https://avatars.githubusercontent.com/u/591103?v=4)](https://github.com/Sweetchuck "Sweetchuck (54 commits)")

---

Tags

composer-pluginscenariossuites

###  Code Quality

TestsCodeception

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/sweetchuck-composer-suite/health.svg)

```
[![Health](https://phpackages.com/badges/sweetchuck-composer-suite/health.svg)](https://phpackages.com/packages/sweetchuck-composer-suite)
```

###  Alternatives

[composer/composer

Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.

29.5k196.2M3.1k](/packages/composer-composer)[friendsofphp/php-cs-fixer

A tool to automatically fix PHP code style

13.5k251.2M25.2k](/packages/friendsofphp-php-cs-fixer)[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k251.7M11.6k](/packages/symfony-framework-bundle)[phpro/grumphp

A composer plugin that enables source code quality checks.

4.3k16.7M1.0k](/packages/phpro-grumphp)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

103519.9k53](/packages/friendsoftypo3-content-blocks)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k43](/packages/civicrm-civicrm-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
