PHPackages                             saucebase/module-installer - 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. saucebase/module-installer

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

saucebase/module-installer
==========================

Custom Composer installer for Sauce Base modules (type: saucebase-module). Installs to modules/&lt;name&gt; (lowercase) with configurable base dir.

v2.7.0(2w ago)11.5k↓41.7%1MITPHPPHP ^8.4CI passing

Since Dec 24Pushed 2w agoCompare

[ Source](https://github.com/saucebase-dev/module-installer)[ Packagist](https://packagist.org/packages/saucebase/module-installer)[ RSS](/packages/saucebase-module-installer/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (10)Dependencies (18)Versions (21)Used By (1)

Saucebase Module Installer
==========================

[](#saucebase-module-installer)

[![PHP Version](https://camo.githubusercontent.com/270717987f5341772d79b57567226e54ed27b2d4199bbdc98a96e2edf24902fa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](#requirements)[![Composer](https://camo.githubusercontent.com/97a043c7b7c47d58a6ec9f61ebb754057d147bdbd50fd28c6284949e046757de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d706f7365722d322e782d3838353633303f6c6f676f3d636f6d706f736572266c6f676f436f6c6f723d7768697465)](#requirements)[![Tests](https://github.com/saucebase-dev/module-installer/actions/workflows/php.yml/badge.svg)](https://github.com/saucebase-dev/module-installer/actions/workflows/php.yml)[![License](https://camo.githubusercontent.com/09f186028fca513d9e0023b7496dd7f7929331b6f61e3af9cf4f6ff0c1081327/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d304137454134)](#license)

A Composer plugin that installs Saucebase modules into the correct directory. It ships with [`saucebase-dev/saucebase`](https://github.com/saucebase-dev/saucebase), so every module your project requires is placed where the app can find and load it.

How It Works
------------

[](#how-it-works)

- Registers a Composer installer for a configurable module package type (defaults to `laravel-module`; the Saucebase app uses `saucebase-module`).
- Installs each module inside a configurable modules directory (`modules/` by default, lowercase).
- Derives the directory name from the package slug: `saucebase/example-module` → `modules/example-module`.
- On `composer update`, **merges** the new version into your existing module directory by default, preserving local edits. Conflicts are staged in the git index for review.
- Removes configurable directories (e.g. `.github`, `.git`) after each install or update.
- Deploys frontend framework files (Vue / React / Svelte) based on the project's `frontend.json` selection.
- Protects path-repository modules (symlinks or local `.git` clones) from being overwritten or deleted.
- Skips folder deletion by default when a module is removed via `composer remove` — the directory stays on disk for manual review.

Requirements
------------

[](#requirements)

- PHP 8.4 or newer
- Composer 2.x
- A project based on `saucebase-dev/saucebase` (the core already requires this plugin)

Installation
------------

[](#installation)

`saucebase-dev/saucebase` already requires this package. When you install the core, Composer pulls in the plugin and activates it through the `Saucebase\\ModuleInstaller\\Plugin` class — no extra configuration is needed for a typical Saucebase project.

Need the installer for a different Composer project? Require it directly:

```
composer require saucebase/module-installer
```

Configuration Reference
-----------------------

[](#configuration-reference)

All options live in the `extra` section of the **root** `composer.json`. Every key is optional.

KeyDefaultDescription`module-type``laravel-module`Composer package type the installer handles.`module-dir``modules`Directory modules are installed into.`module-exclude-dirs``[".github", ".git"]`Directories removed from each module after install/update.`module-update-strategy``merge``merge` preserves local edits; `overwrite` replaces entirely.`module-delete-on-remove``false`Set to `true` to delete the module folder on `composer remove`.Example (the Saucebase app configuration):

```
{
    "extra": {
        "module-type": "saucebase-module",
        "module-dir": "modules"
    }
}
```

Configuring the Module Type
---------------------------

[](#configuring-the-module-type)

The installer registers the `laravel-module` package type by default. Override it in the root package `extra` section:

```
{
    "extra": {
        "module-type": "saucebase-module"
    }
}
```

Any module packages must set their `composer.json` `type` to the same value.

Configuring the Install Location
--------------------------------

[](#configuring-the-install-location)

By default, modules are installed under `modules/` at the project root. Change this with the `module-dir` key:

```
{
    "extra": {
        "module-dir": "custom-modules"
    }
}
```

With the configuration above, `saucebase/example-module` installs to `custom-modules/example-module`.

Configuring Excluded Directories
--------------------------------

[](#configuring-excluded-directories)

After each install or update, the installer removes directories that should not land in production. The default list is `.github` and `.git`. Override it with `module-exclude-dirs`:

```
{
    "extra": {
        "module-exclude-dirs": [".github", ".git", ".vscode", "tests"]
    }
}
```

Set it to `[]` to skip all removal. The configured list replaces the default entirely.

Configuring Update Behaviour
----------------------------

[](#configuring-update-behaviour)

By default, when you run `composer update`, the installer **merges** the new package version into your existing module directory rather than replacing it.

StrategyWhat happens on `composer update``merge` *(default)*New files from the package are added. Your edited files are kept as-is. Conflicts between your edits and upstream changes are staged in the git index (conflict markers in the file, both sides visible in `git diff`).`overwrite`The module directory is replaced entirely with the new package contents. All local edits are lost.### Keeping your customisations (default)

[](#keeping-your-customisations-default)

No configuration needed. Running `composer update` adds new files without touching files you have already edited.

> **Note:** Because your local files take precedence, bug fixes or updates to files you have customised will **not** be applied automatically. To pick up an upstream change to a specific file, delete it and re-run `composer update`.

### Merge conflicts

[](#merge-conflicts)

When both you and the upstream package changed the same file, the installer stages a 3-way conflict in the git index (stages 1/2/3). The working-tree file contains standard conflict markers and `git status` shows it as a conflict for normal resolution via `git mergetool` or your editor.

### Full overwrite (CI / reproducible builds)

[](#full-overwrite-ci--reproducible-builds)

Set the strategy to `overwrite` to produce an exact copy of the package on every update:

```
{
    "extra": {
        "module-update-strategy": "overwrite"
    }
}
```

This is recommended for CI pipelines and staging environments where reproducibility matters more than preserving local changes.

### Getting a completely fresh copy of a module

[](#getting-a-completely-fresh-copy-of-a-module)

With the `merge` strategy (default), delete the module directory and run `composer update`:

```
rm -rf modules/example-module
composer update vendor/example-module
```

The installer performs a clean install into the now-empty path.

Skipping Module Deletion on Remove
----------------------------------

[](#skipping-module-deletion-on-remove)

By default, running `composer remove` on a module **does not delete the module directory**. The package is removed from `composer.lock` and Composer's tracking, but the folder stays on disk for manual review.

```
- Skipping deletion of module directory (set module-delete-on-remove: true to enable): modules/example-module

```

To restore the old behaviour and delete the folder automatically:

```
{
    "extra": {
        "module-delete-on-remove": true
    }
}
```

> **Why skip by default?** A `composer remove` followed by `composer install` in CI will not re-download an untracked folder — but it also will not delete your work. The conservative default prevents accidental data loss; opt in to deletion explicitly.

Frontend Framework Support
--------------------------

[](#frontend-framework-support)

When a module ships JavaScript resources for multiple frameworks (Vue, React, or Svelte), the installer copies only the files for the active framework flat into `resources/js/` and removes the other framework subdirectories.

The active framework is read from `frontend.json` in the project root:

```
{
    "framework": "vue"
}
```

Valid values are `vue`, `react`, and `svelte`. If `frontend.json` is absent, unreadable, or has `"dev": true`, no framework files are copied and all framework subdirectories are left in place.

Module packages should ship framework files under subdirectories matching the framework name:

```
resources/
  js/
    vue/
      Component.vue
    react/
      Component.tsx

```

After install with `"framework": "vue"` active, the result is:

```
resources/
  js/
    Component.vue   ← copied flat from vue/

```

Creating Sauce Base Modules
---------------------------

[](#creating-sauce-base-modules)

To ship a module that works with this installer:

1. Set the package `type` in the module `composer.json` to whatever the application expects (e.g. `saucebase-module`).
2. Organise module code inside the directory the installer will create (e.g. `modules/your-module-name`).
3. Have consumers install the module through Composer:

    ```
    composer require vendor/your-module-name
    ```

    The plugin derives the install directory from the package slug. `vendor/your-module-name` installs to `modules/your-module-name` (or the configured `module-dir`).

Local Development
-----------------

[](#local-development)

Clone the repository and install dependencies:

```
composer install
```

Useful scripts:

- `composer test` — run the PHPUnit 12 suite (`tests/`).
- `./vendor/bin/pint` — apply Laravel Pint formatting (add `--test` for CI-style checks).
- `composer validate` — verify Composer metadata.

License
-------

[](#license)

Licensed under the [MIT License](./LICENSE).

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance97

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 91.3% 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 ~9 days

Recently: every ~2 days

Total

19

Last Release

16d ago

Major Versions

v0.0.6 → v1.0.02026-03-17

v1.0.1 → v2.0.02026-05-13

### Community

Maintainers

![](https://www.gravatar.com/avatar/b984fc5c4f372285b03b0926ca33af6d9d56fba171efaeb674ec120a82650efc?d=identicon)[saucebase](/maintainers/saucebase)

---

Top Contributors

[![roble](https://avatars.githubusercontent.com/u/3231587?v=4)](https://github.com/roble "roble (95 commits)")[![sauce-base](https://avatars.githubusercontent.com/u/226096358?v=4)](https://github.com/sauce-base "sauce-base (9 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/saucebase-module-installer/health.svg)

```
[![Health](https://phpackages.com/badges/saucebase-module-installer/health.svg)](https://phpackages.com/packages/saucebase-module-installer)
```

###  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)[phpro/grumphp

A composer plugin that enables source code quality checks.

4.3k16.7M1.0k](/packages/phpro-grumphp)[civicrm/civicrm-core

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

751291.4k43](/packages/civicrm-civicrm-core)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

21866.0M1.7k](/packages/drupal-core)

PHPackages © 2026

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