symplify / monorepo-builder
Not only Composer tools to build a Monorepo.
Requires
- php: >=8.2
- nette/utils: ^4.0.5
- phar-io/version: ^3.2
- sebastian/diff: ^6.0 || ^7.0 || ^8.0
- symfony/config: ^7.0 || ^8.0
- symfony/console: ^7.0 || ^8.0
- symfony/dependency-injection: ^7.0 || ^8.0
- symfony/filesystem: ^7.0 || ^8.0
- symfony/finder: ^7.0 || ^8.0
- symfony/http-kernel: ^7.0 || ^8.0
- symfony/process: ^7.0 || ^8.0
- webmozart/assert: ^1.11 || ^2.0
Requires (Dev)
- php-parallel-lint/php-parallel-lint: ^1.3
- phpstan/extension-installer: 1.4.3
- phpstan/phpstan: ^2.1.22
- phpunit/phpunit: ^11.0
- rector/rector: ^2.1.3
- symplify/easy-ci: ^11.3
- symplify/easy-coding-standard: ^12.0
- symplify/phpstan-extensions: ^12.0.1
- symplify/phpstan-rules: ^14.6.12
- tomasvotruba/class-leak: ^2.0.5
- tomasvotruba/unused-public: ^2.0.1
- tracy/tracy: ^2.9
- dev-main
- 12.7.0
- 12.6.2
- 12.6.1
- 12.6.0
- 12.5.2
- 12.5.1
- 12.5.0
- 12.4.5
- 12.4.4
- 12.4.3
- 12.4.2
- 12.4.1
- 12.4.0
- 12.3.2
- 12.3.1
- 12.3.0
- 12.2.0
- 12.1.2
- 12.1.1
- 12.1.0
- 12.0.2
- 12.0.1
- 12.0.0
- 11.2.23
- 11.2.22
- 11.2.21
- 11.2.20
- 11.2.19
- 11.2.18
- 11.2.17
- 11.2.16
- 11.2.15
- 11.2.14
- 11.2.13
- 11.2.12
- 11.2.11
- 11.2.10
- 11.2.9
- 11.2.8
- 11.2.7
- 11.2.6
- 11.2.5
- 11.2.4.72
- 11.2.4
- 11.2.3.72
- 11.2.3
- 11.2.2.72
- 11.2.2
- 11.2.1.72
- 11.2.1
- 11.2.0.72
- 11.2.0
- 11.1.32.72
- 11.1.32
- 11.1.31.72
- 11.1.31
- 11.1.30.72
- 11.1.30
- 11.1.29.72
- 11.1.29
- 11.1.28.72
- 11.1.28
- 11.1.27
- 11.1.26.72
- 11.1.26
- 11.1.25.72
- 11.1.25
- 11.1.24
- 11.1.23
- 11.1.22
- 11.1.21
- 11.1.20
- 11.1.19
- 11.1.18
- 11.1.17
- 11.1.16
- 11.1.15
- 11.1.14
- 11.1.13
- 11.1.12
- 11.1.11
- 11.1.10
- 11.1.9
- 11.1.8
- 11.1.7
- 11.1.6
- 11.1.5
- 11.1.4
- 11.1.3
- 11.1.2
- 11.1.1
- 11.1.0
- 11.0.9
- 11.0.8
- 11.0.7
- 11.0.6
- 11.0.5
- 11.0.4
- 11.0.3
- 11.0.2
- 11.0.1
- 10.3.3
- 10.3.2
- 10.3.1
- 10.3.0
- 10.2.11
- 10.2.10
- 10.2.9
- 10.2.7
- 10.2.6
- 10.2.5
- 10.2.4
- 10.2.3
- 10.2.2
- 10.2.1
- 10.2.0
- 10.1.4
- 10.1.3
- 10.1.2
- 10.1.1
- 10.1.0
- 10.0.25
- 10.0.24
- 10.0.23
- 10.0.22
- 10.0.21
- 10.0.20
- 10.0.19
- 10.0.18
- 10.0.17
- 10.0.16
- 10.0.15
- 10.0.14
- 10.0.13
- 10.0.12
- 10.0.11
- 10.0.10
- 10.0.9
- 10.0.7
- 10.0.6
- 10.0.5
- 10.0.4
- 10.0.3
- 10.0.2
- 10.0.1
- 10.0.0
- 10.0.0-beta17
- 10.0.0-beta15
- 10.0.0-beta14
- 10.0.0-beta13
- 10.0.0-beta12
- 10.0.0-beta11
- 10.0.0-beta10
- 10.0.0-beta9
- 10.0.0-beta8
- 10.0.0-beta7
- 10.0.0-beta6
- 10.0.0-beta5
- 10.0.0-beta4
- 10.0.0-beta3
- 10.0.0-beta2
- 10.0.0-beta1
- 9.4.70
- 9.4.69
- 9.4.68
- 9.4.67
- 9.4.65
- 9.4.64
- 9.4.63
- 9.4.62
- 9.4.61
- 9.4.60
- 9.4.59
- 9.4.58
- 9.4.57
- 9.4.56
- 9.4.55
- 9.4.54
- 9.4.53
- 9.4.52
- 9.4.51
- 9.4.50
- 9.4.49
- 9.4.48
- 9.4.47
- 9.4.46
- 9.4.45
- 9.4.44
- 9.4.43
- 9.4.42
- 9.4.41
- 9.4.40
- 9.4.39
- 9.4.38
- 9.4.37
- 9.4.36
- 9.4.35
- 9.4.34
- 9.4.33
- 9.4.32
- 9.4.31
- 9.4.30
- 9.4.29
- 9.4.28
- 9.4.27
- 9.4.26
- 9.4.25
- 9.4.24
- 9.4.23
- 9.4.22
- 9.4.21
- 9.4.20
- 9.4.19
- 9.4.18
- 9.4.17
- 9.4.16
- 9.4.15
- 9.4.14
- 9.4.13
- 9.4.12
- 9.4.11
- 9.4.10
- 9.4.9
- 9.4.8
- 9.4.7
- 9.4.6
- 9.4.5
- 9.4.4
- 9.4.3
- 9.4.2
- v9.4.1
- v9.4.0
- v9.3.27
- v9.3.26
- v9.3.25
- v9.3.24
- v9.3.23
- v9.3.22
- v9.3.21
- v9.3.20
- v9.3.19
- v9.3.18
- v9.3.17
- v9.3.16
- v9.3.15
- v9.3.14
- v9.3.13
- v9.3.12
- v9.3.11
- v9.3.10
- v9.3.8
- v9.3.6
- v9.3.5
- v9.3.4
- v9.3.3
- v9.3.1
- v9.3.0
- v9.2.24
- v9.2.23
- v9.2.22
- v9.2.21
- v9.2.20
- v9.2.19
- v9.2.18
- v9.2.17
- v9.2.16
- v9.2.15
- v9.2.14
- v9.2.13
- v9.2.12
- v9.2.11
- v9.2.10
- v9.2.9
- v9.2.8
- v9.2.7
- v9.2.6
- v9.2.5
- v9.2.4
- v9.2.3
- v9.2.2
- 9.2.1
- 9.2.0
- 9.1.9
- 9.1.8
- 9.1.7
- 9.1.6
- 9.1.5
- 9.1.4
- 9.1.3
- 9.1.1
- 9.1.0
- 9.0.50
- 9.0.49
- 9.0.48
- 9.0.47
- 9.0.46
- 9.0.45
- 9.0.44
- 9.0.43
- 9.0.42
- 9.0.41
- 9.0.40
- 9.0.39
- 9.0.38
- 9.0.37
- 9.0.36
- 9.0.35
- 9.0.34
- 9.0.33
- 9.0.32
- 9.0.31
- 9.0.30
- 9.0.29
- 9.0.28
- 9.0.27
- 9.0.26
- 9.0.25
- 9.0.24
- 9.0.23
- 9.0.22
- 9.0.21
- 9.0.20
- 9.0.19
- 9.0.18
- 9.0.17
- 9.0.16
- 9.0.15
- 9.0.14
- 9.0.13
- 9.0.12
- 9.0.11
- 9.0.10
- 9.0.9
- 9.0.8
- 9.0.7
- 9.0.6
- 9.0.5
- 9.0.4
- 9.0.3
- 9.0.2
- 9.0.1
- 9.0.0
- 9.0.0-rc1
- 9.0.0-BETA9
- 9.0.0-BETA8
- 9.0.0-BETA7
- 9.0.0-BETA6
- 9.0.0-BETA5
- 9.0.0-BETA4
- 9.0.0-BETA3
- 9.0.0-BETA2
- 9.0.0-BETA1
- 8.3.48
- 8.3.47
- 8.3.46
- 8.3.45
- 8.3.44
- 8.3.43
- 8.3.42
- 8.3.41
- 8.3.40
- 8.3.39
- 8.3.38
- 8.3.37
- 8.3.36
- 8.3.35
- 8.3.34
- 8.3.33
- 8.3.32
- 8.3.31
- 8.3.30
- 8.3.29
- 8.3.28
- 8.3.27
- 8.3.26
- 8.3.25
- 8.3.24
- 8.3.23
- 8.3.22
- 8.3.21
- 8.3.20
- 8.3.19
- 8.3.18
- 8.3.17
- 8.3.16
- 8.3.15
- 8.3.14
- 8.3.13
- 8.3.12
- 8.3.11
- 8.3.10
- 8.3.7
- 8.3.6
- 8.3.5
- 8.3.4
- 8.3.3
- 8.3.2
- 8.3.1
- 8.3.0
- 8.2.27
- 8.2.26
- 8.2.25
- 8.2.24
- 8.2.22
- 8.2.21
- 8.2.20
- 8.2.19
- 8.2.18
- 8.2.17
- v8.2.16
- v8.2.15
- v8.2.14
- v8.2.13
- v8.2.12
- v8.2.11
- v8.2.10
- v8.2.9
- v8.2.8
- v8.2.7
- v8.2.6
- v8.2.5
- v8.2.4
- v8.2.3
- v8.2.2
- v8.2.1
- v8.2.0
- v8.1.20
- v8.1.19
- v8.1.18
- v8.1.17
- v8.1.16
- v8.1.15
- v8.1.14
- v8.1.13
- v8.1.12
- v8.1.11
- v8.1.10
- v8.1.9
- v8.1.8
- v8.1.7
- v8.1.6
- v8.1.4
- v8.1.3
- v8.1.2
- v8.1.1
- v8.1.0
- v8.0.1
- v8.0.0
- v8.0.0-beta4
- v8.0.0-beta3
- v8.0.0-beta2
- v8.0.0-beta1
- v7.3.18
- v7.3.17
- v7.3.16
- v7.3.15
- v7.3.14
- v7.3.13
- v7.3.11
- v7.3.10
- v7.3.9
- v7.3.8
- v7.3.7
- v7.3.6
- v7.3.5
- v7.3.4
- v7.3.3
- v7.3.2
- v7.3.1
- v7.3.0
- v7.2.20
- v7.2.19
- v7.2.18
- v7.2.17
- v7.2.16
- v7.2.15
- v7.2.14
- v7.2.13
- v7.2.12
- v7.2.11
- v7.2.10
- v7.2.8
- v7.2.7
- v7.2.6
- v7.2.5
- v7.2.4
- v7.2.3
- v7.2.2
- v7.2.1
- v7.2.0
- v7.1.3
- v7.1.2
- v7.1.1
- v7.1.0
- v7.0.2
- v7.0.1
- v7.0.0
- v6.1.0
- v6.0.5
- v6.0.4
- v6.0.3
- v6.0.2
- v6.0.1
- v6.0.0
- v5.4.16
- v5.4.15
- v5.4.14
- v5.4.13
- v5.4.12
- v5.4.11
- v5.4.10
- v5.4.9
- v5.4.8
- v5.4.7
- v5.4.6
- v5.4.5
- v5.4.4
- v5.4.3
- v5.4.2
- v5.4.1
- v5.4.0
- v5.3.12
- v5.3.11
- v5.3.10
- v5.3.9
- v5.3.8
- v5.3.7
- v5.3.6
- v5.3.5
- v5.3.4
- v5.3.2
- v5.3.1
- v5.3.0
- v5.2.22
- v5.2.20
- v5.2.19
- v5.2.18
- v5.2.17
- v5.2.16
- v5.2.15
- v5.2.14
- v5.2.13
- v5.2.12
- v5.2.11
- v5.2.10
- v5.2.9
- v5.2.8
- v5.2.7
- v5.2.6
- v5.2.5
- v5.2.4
- v5.2.3
- v5.2.2
- v5.2.1
- v5.2.0
- v5.1.4
- v5.1.3
- v5.1.2
- v5.1.1
- v5.1.0
- v5.0.2
- v5.0.1
- v5.0.0
- v4.8.0
- v4.7.0
- v4.6.1
- v4.6.0
- v4.5.1
- v4.5.0
- v4.4.2
This package is auto-updated.
Last update: 2026-04-24 05:51:13 UTC
README
A set of tools for managing PHP monorepos: merging composer.json files, validating package versions, releasing with automation, and more.
Install
composer require monorepo-php/monorepo --dev
Requires PHP 8.2+. For PHP 8.1, use symplify/monorepo-builder:^11.2 (no longer maintained).
Quick Start
# 1. Scaffold a basic monorepo layout (one time) vendor/bin/monorepo-builder init # 2. Fold every package's composer.json into the root composer.json vendor/bin/monorepo-builder merge # 3. Cut a release when you're ready vendor/bin/monorepo-builder release v1.0
All configuration goes in monorepo-builder.php at your project root. See Configuration for the full list of options.
Commands
init
Generates a basic monorepo skeleton (a packages/ directory and a starter monorepo-builder.php) so you can start adding packages immediately:
vendor/bin/monorepo-builder init
Run once at the start of a new monorepo. Existing files are not overwritten.
merge
Merges all sections from package composer.json files into the root composer.json. For the reverse direction, see propagate.
vendor/bin/monorepo-builder merge
Behavior:
- All sections are merged, including standard (
require,autoload, etc.) and custom ones (scripts-aliases,abandoned, etc.) - If a package appears in both
requireandrequire-dev, therequireentry takes priority - The original key order of the root
composer.jsonis preserved; new sections are appended at the end
To customize what gets merged (append / remove data, reorder sections, skip autoload merging, etc.) see Customizing merge output.
validate
Checks that all packages use the same version for shared dependencies:
vendor/bin/monorepo-builder validate
bump-interdependency
Updates mutual dependencies between packages to a given version:
vendor/bin/monorepo-builder bump-interdependency "^4.0"
propagate
Propagates versions from root composer.json back to each package's composer.json (the reverse of merge):
vendor/bin/monorepo-builder propagate
package-alias
Updates the branch-alias in every package composer.json to match the current version:
vendor/bin/monorepo-builder package-alias
To customize the alias format string, see Custom alias format under Configuration.
localize-composer-paths
Sets mutual package paths to local packages for pre-split testing:
vendor/bin/monorepo-builder localize-composer-paths
release
Automates the release process: bumping dependencies, tagging, pushing, and updating changelogs.
vendor/bin/monorepo-builder release v7.0
Preview what will happen without making changes:
vendor/bin/monorepo-builder release v7.0 --dry-run
Release by semver level (patch, minor, or major):
# current v0.7.1 → v0.7.2
vendor/bin/monorepo-builder release patch
The default pipeline runs TagVersionReleaseWorker followed by PushTagReleaseWorker. To customize the pipeline (add workers, reorder, disable defaults, enable LTS-aware tag resolution), see Customizing the release pipeline.
Configuration
All configuration lives in monorepo-builder.php at your project root. Every option below is set on the MBConfig instance passed into the configurator closure:
use Symplify\MonorepoBuilder\Config\MBConfig; return static function (MBConfig $mbConfig): void { // your configuration here };
Package discovery
By default, packages are discovered from ./packages. To customize:
return static function (MBConfig $mbConfig): void { $mbConfig->packageDirectories([ __DIR__ . '/packages', __DIR__ . '/projects', ]); // exclude specific packages $mbConfig->packageDirectoriesExcludes([__DIR__ . '/packages/secret-package']); };
Customizing merge output
These options shape what vendor/bin/monorepo-builder merge writes into the root composer.json.
Append / remove data after merge
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection; use Symplify\MonorepoBuilder\Config\MBConfig; use Symplify\MonorepoBuilder\ValueObject\Option; return static function (MBConfig $mbConfig): void { // add data after merge (supports any composer.json key) $mbConfig->dataToAppend([ ComposerJsonSection::AUTOLOAD_DEV => [ 'psr-4' => [ 'Symplify\Tests\\' => 'tests', ], ], ComposerJsonSection::REQUIRE_DEV => [ 'phpstan/phpstan' => '^2.1', ], ]); // remove data after merge $mbConfig->dataToRemove([ ComposerJsonSection::REQUIRE => [ // removed by key, version is irrelevant 'phpunit/phpunit' => '*', ], ComposerJsonSection::REPOSITORIES => [ Option::REMOVE_COMPLETELY, ], ]); };
Section ordering
By default, the original key order of root composer.json is preserved. To enforce a specific order:
use Symplify\MonorepoBuilder\Config\MBConfig; use Symplify\MonorepoBuilder\Merge\JsonSchema; return static function (MBConfig $mbConfig): void { $mbConfig->composerSectionOrder(JsonSchema::getProperties()); };
Skip autoload merging for selected packages
By default, every internal package's autoload and autoload-dev PSR-4 entries are folded into the root composer.json so that vendor/bin/phpunit and other root-level tooling can resolve every namespace. The three scenarios below cover when you'd want to skip part or all of that merging — pick the one that matches your monorepo:
Scenario 1 — Default monorepo of libraries. No skip needed. The root composer.json autoload aggregates every internal library's PSR-4 mapping, so any namespace resolves from the root vendor.
Scenario 2 — Mixed monorepo with libraries symlinked + apps not required from root. When disablePackageReplace() is on (libraries are real path-repo deps, Composer symlinks them into vendor/), the libraries' autoload is registered automatically by Composer via vendor/composer/autoload_psr4.php. Folding them into the root composer.json would duplicate that registration. Skip autoload merging for libraries only — apps' autoload still merges so root-level scripts can find them:
use Symplify\MonorepoBuilder\Config\AutoloadSection; use Symplify\MonorepoBuilder\Config\MBConfig; use Symplify\MonorepoBuilder\Config\PackageType; return static function (MBConfig $mbConfig): void { $mbConfig->disablePackageReplace(); $mbConfig->disableAutoloadMerge( sections: [AutoloadSection::Autoload], forTypes: [PackageType::Library], ); };
Result: root autoload contains apps' PSR-4 entries but NOT libraries'. Root autoload-dev still aggregates everything (see "Why autoload-dev is independent" below).
Scenario 3 — Custom merge. To turn off both sections entirely (you handle merging yourself, e.g. via a custom decorator):
use Symplify\MonorepoBuilder\Config\AutoloadSection; use Symplify\MonorepoBuilder\Config\MBConfig; return static function (MBConfig $mbConfig): void { $mbConfig->disableAutoloadMerge( sections: [AutoloadSection::Autoload, AutoloadSection::AutoloadDev], forTypes: [], ); };
Result: root autoload and autoload-dev are untouched by monorepo-builder merge.
API reference:
disableAutoloadMerge(array $sections, array $forTypes)— both arguments are required.$sections: a non-empty list ofAutoloadSectioncases (Autoload,AutoloadDev).$forTypes: a list of composer.jsontypefilter values. Each element may be either aPackageTypeenum case (preferred for the four Composer schema types:Library,Project,Metapackage,ComposerPlugin) or a non-empty string (escape hatch for ecosystem types defined bycomposer/installerssuch as'wordpress-plugin','drupal-module','symfony-bundle', and for user-defined custom types). Mixing enum cases and strings in the same call is allowed; multiple types are OR-matched. The two filter channels are intentionally distinct: pass an empty array (forTypes: []) to skip every package regardless of type, OR pass a non-empty list of types to skip ONLY packages whosecomposer.jsondeclares the matchingtypeliterally. Composer's "missingtypedefaults to library" rule does NOT extend the filter — a package without an explicittypefield is NOT swept up byforTypes: [PackageType::Library]. If you want the filter to catch an untyped package, declaretype: library(or whichever) in that package'scomposer.json.
- Repeated calls follow last-call-wins semantics PER section. Calls touching different sections compose; calls touching the same section override.
Migrating from the previous binary API: The earlier zero-argument form $mbConfig->disableAutoloadMerge(); continues to work but is deprecated and emits an E_USER_DEPRECATED notice. It maps to the full-kill behavior — equivalent to disableAutoloadMerge(sections: [AutoloadSection::Autoload, AutoloadSection::AutoloadDev], forTypes: []). Update existing config files at your convenience. The legacy MBConfig::isAutoloadMergeDisabled() getter is also kept as a deprecated convenience that returns true only when both sections are configured to skip merging for all packages — prefer MBConfig::shouldSkipAutoload($packageType) and MBConfig::shouldSkipAutoloadDev($packageType) for new code.
Why autoload-dev is independent
Composer treats autoload-dev as a root-only section: dev autoload entries from path-repo dependencies are NEVER registered in the consumer's vendor/composer/autoload_psr4.php. (See Composer schema docs — autoload-dev.)
Practical consequence: if your CI runs vendor/bin/phpunit from the monorepo root and expects to discover library test classes, those test classes are reachable ONLY because monorepo-builder merge has folded each library's autoload-dev PSR-4 into the root composer.json. Skipping AutoloadSection::AutoloadDev from root merge therefore breaks cross-package PHPUnit discovery — skip it only when you're handling test discovery another way.
Skip the package-replace section
By default, monorepo-builder merge writes a replace section into the root composer.json listing every internal package at self.version. This is correct for monorepos that publish a single combined dependency surface — Composer then refuses to install any external copy of those packages.
Some monorepos do NOT want this:
- Apps that require their own internal libraries via
pathrepositories and rely on Composer's symlink installation (thereplaceentry would short-circuit the symlink) - Monorepos with mixed
type: librarypackages andtype: projectapps where the apps need real installs of the libs
To skip writing the replace section entirely:
use Symplify\MonorepoBuilder\Config\MBConfig; return static function (MBConfig $mbConfig): void { $mbConfig->disablePackageReplace(); };
This pairs naturally with Scenario 2 of the autoload skip section above. With both opt-outs on, your path-repository-based libraries get symlink-installed by Composer and only your apps' autoload entries land in the root composer.json.
Customizing the release pipeline
These options shape what vendor/bin/monorepo-builder release does on each invocation.
Custom workers
TagVersionReleaseWorker and PushTagReleaseWorker are enabled by default. Add more workers or customize the order:
use Symplify\MonorepoBuilder\Config\MBConfig; use Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateReplaceReleaseWorker; return static function (MBConfig $mbConfig): void { $mbConfig->workers([ UpdateReplaceReleaseWorker::class, SetCurrentMutualDependenciesReleaseWorker::class, AddTagToChangelogReleaseWorker::class, TagVersionReleaseWorker::class, PushTagReleaseWorker::class, SetNextMutualDependenciesReleaseWorker::class, UpdateBranchAliasReleaseWorker::class, PushNextDevReleaseWorker::class, ]); };
To disable the default workers (and define your pipeline from scratch):
return static function (MBConfig $mbConfig): void { $mbConfig->disableDefaultWorkers(); };
You can also add custom workers by implementing ReleaseWorkerInterface.
Branch-aware tag validation (LTS)
If you maintain multiple version lines, the release command may reject older versions because it compares against the most recent tag globally. Enable branch-aware validation to compare only within the same major version:
use Symplify\MonorepoBuilder\Config\MBConfig; use Symplify\MonorepoBuilder\Contract\Git\TagResolverInterface; use Symplify\MonorepoBuilder\Git\BranchAwareTagResolver; return static function (MBConfig $mbConfig): void { $services = $mbConfig->services(); $services->set(BranchAwareTagResolver::class); $services->alias(TagResolverInterface::class, BranchAwareTagResolver::class); };
Custom alias format
vendor/bin/monorepo-builder package-alias writes a branch-alias entry into every package composer.json. To override the format string used:
use Symplify\MonorepoBuilder\Config\MBConfig; return static function (MBConfig $mbConfig): void { // default: "<major>.<minor>-dev" $mbConfig->packageAliasFormat('<major>.<minor>.x-dev'); };
Package Splitting
To split packages into separate repositories, use symplify/github-action-monorepo-split with GitHub Actions.