Skip to content

Publishing a Module ​

Introduction ​

A module is three ordinary Composer packages. Publishing it is publishing those packages — to Packagist, to a private repository, or as a Git repository a site adds itself. Sites then install it like any kitloom module: Installing Modules.

Before you publish ​

Names ​

kitloom:make-module --vendor=acme already named everything after your vendor:

text
acme/reviews            Acme\Reviews\            config acme-reviews
acme/reviews-filament   Acme\Reviews\Filament\
acme/reviews-nova       Acme\Reviews\Nova\

The admin packages must stay <domain package>-filament and <domain package>-nova and require the domain package directly: that is how the Modules screen finds a module's admin and unloads it together with the module.

Requirements ​

The generated packages require each other and the kitloom packages with @dev, which works only through a path repository. Before publishing, require versions:

json
"require": {
    "php": "^8.2",
    "illuminate/support": "^11.0|^12.0",
    "acme/reviews": "^1.0",
    "kitloom/settings-filament": "^1.0",
    "kitloom/wp-schema-filament": "^1.0",
    "filament/filament": "^5.0"
}

Require every kitloom package you use classes from — not only the one that happens to bring the others along. A package that is not required can be switched off on the Modules screen, or be missing on another site, and your module breaks there.

The Modules screen ​

extra.kitloom.module in the domain package's composer.json is what lists the package as a module:

json
"extra": {
    "kitloom": {
        "module": {
            "name": "Reviews",
            "description": "Book reviews with ratings and pages of their own."
        }
    }
}

Only the domain package declares it. The screen shows the name, the description and the version Composer installed; it says what keeps a module from being switched off and what has to be switched on first. While your module is on, the modules it requires cannot be switched off; switching yours off unloads its admin package too. See Enabling & Disabling.

License ​

Pick a license and put it both in composer.json ("license": "MIT", or "proprietary" for a paid module) and in a LICENSE.md file at the package root.

A free package must not require a paid one: nobody could install it without buying the other. kitloom's own packages follow this — the Nova edition is paid, and every -nova package is.

README ​

Every kitloom package has a README with the same sections — keep them:

  • What is inside — what the package does, and where its data lives (tables, options, meta keys).
  • What the application overrides — the config switches, the model in the registry, the contracts it binds, the resource to subclass.
  • Configuration — the config file and its publish tag.

Tests and checks ​

The tests run on a bare skeleton — no code of a particular site assumed. Run Pint and your static analysis on the packages; a module from the generator passes PHPStan at level 5 with Larastan, the level kitloom's own packages are checked at.

Versions ​

Version the three packages together: the admin packages require ^1.0 of the domain package, and a change in what the domain package gives its admins is a new major version for all three.

What is a breaking change for a module:

  • a renamed or removed meta key, option or table column — sites have data under the old name. Read the old one, write the new one, and keep reading the old one for a major version;
  • a changed page part: its key() or the keys of toArray() — themes rely on them;
  • a renamed permission — roles granted it on sites;
  • a changed contract or tag others implement.

Publishing ​

bash
# Each package in a repository of its own, tagged:
git tag v1.0.0 && git push --tags
# then submit the repository at packagist.org
json
{
    "repositories": [
        { "type": "composer", "url": "https://packages.acme.dev" }
    ]
}
json
{
    "repositories": [
        { "type": "vcs", "url": "https://git.acme.dev/acme/reviews.git" },
        { "type": "vcs", "url": "https://git.acme.dev/acme/reviews-filament.git" }
    ]
}

Keeping the three packages in one repository while you develop is fine — that is how kitloom itself is built. Split them into a repository each for Packagist, or serve them from a private Composer repository that reads the monorepo.

Installing it on a site ​

bash
composer require acme/reviews acme/reviews-filament
php artisan migrate

The module plugs itself in on the next request. Nothing else is needed — if it is, the module is not finished: see the rules.