Appearance
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 oftoArray()— 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.orgjson
{
"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 migrateThe module plugs itself in on the next request. Nothing else is needed — if it is, the module is not finished: see the rules.