A module ships with Convoro; an extension is a package somebody installs into extensions/. The code is the same shape — the console can scaffold and package one for you.

Structurally they are the same: a manifest, a class with register() and boot(), routes, migrations, services and templates. The difference is where it lives and how it arrives.

The console has the whole lifecycle:

php tools/convoro ext:scaffold my-thing
php tools/convoro ext:list
php tools/convoro ext:install path/to/thing.zip
php tools/convoro ext:enable my-thing
php tools/convoro ext:disable my-thing
php tools/convoro ext:package my-thing
php tools/convoro ext:uninstall my-thing

🚨 extensions/ is site state, not source. It is excluded from deployment for the same reason content/ is — a deploy that syncs the source tree over it uninstalls every extension the operator added.

🚨 Disabling and uninstalling are different. Disabling hides; uninstalling removes. Data is never touched by the first, and that distinction should hold in your own code too.

Sign in to say whether this helped.