Ui5Module
Introduction
A Ui5Module is the top-level container for all UI5 artifacts belonging to a domain (e.g. Users, Timesheet, Portal). Each module wraps exactly one UI5 application or one UI5 library, plus that domain's subordinate artifacts and its platform integration (manifest scope, source strategy, auth boundary).
A module is a container, not an artifact — it implements Ui5ModuleInterface, not the artifact contract, and has no title of its own. Its identity is its namespace, which it reflects from its root artifact (see below). What it does carry is the version every one of its artifacts runs under (see The version below).
App modules may define subordinate artifacts — cards, tiles, actions, resources, reports, dashboards. Libraries are intentionally lightweight and define none.
Identity — the module namespace
A module is keyed by its namespace (e.g. com.acme.portal): the dotted token that uniquely identifies it and becomes its URL segment (dots → slashes — /ui5/app/com/acme/portal@…).
The module does not declare its namespace. The root artifact (the App or Library) owns the NAMESPACE constant, and getNamespace() derives from it (getArtifactRoot()->getNamespace()) — so the module and its artifact share one source of truth and can never drift.
Lifecycle & Creation
Modules are not created explicitly. ui5:app / ui5:lib scaffold the module alongside its root artifact:
php artisan ui5:app Users --create \
--package-prefix=acme --php-ns-prefix=Acme --vendor="Acme GmbH"
# → UsersModule + UsersApp
php artisan ui5:lib Core --create --package-prefix=acme --php-ns-prefix=Acme
# → CoreModule + CoreLibraryThe identity options carry your vendor's prefixes; neither generator has defaults for them — see App and Library. changed in 3.0The generators no longer fall back to our vendor names.
The name (Users, Core) sets the directory and class names; the namespace is written onto the artifact's NAMESPACE constant, read from the UI5 source project.
⚠️ A module contains an application or a library — never both. This is enforced by the architecture and reflected in the interface.
The version
since 7.0 The module holds the version, as a typed constant:public const string VERSION.Every artifact of the module runs under it, and it is the @{ver} of every address the module's artifacts are served at — app/{ns}@{ver}/…, card/{ns}@{ver}/…, api/{ns}@{ver}/…. No artifact declares a version of its own; one that does is refused when the registry loads, and a module without a version fails at boot.
The version decides how long a browser keeps a file. A built file asked for under the module's version goes out immutable: the browser never asks for it again. Bump the version with every release that changes a served file — views, controllers, bundles, a card's translations — and php artisan ui5:doctor reports a module whose served files changed since its last bump (core.W7). In a workspace the source is live and is revalidated whatever the version says.
A package that ships several modules gives them one version: one module holds the literal, the others refer to it.
class PartnersModule extends AbstractUi5Module
{
public const string ARTIFACT_ROOT = PartnersApp::class;
public const string VERSION = SdkModule::VERSION;
}ui5:app and ui5:lib write the version on the module they generate, taken once from the source's sap.app/applicationVersion or .library; after that it is kept by hand.
Artifact Composition
A module declares its contents once, as class names, in two typed constants: its root — the App or the Library — in ARTIFACT_ROOT, every other artifact in ARTIFACTS. changed in 4.0The getters (getApp(), getCards(), getActions(), …) are gone; a module names its artifacts instead.
class OffersModule extends AbstractUi5Module
{
public const string ARTIFACT_ROOT = OffersApp::class;
public const string VERSION = '1.3.0';
public const array ARTIFACTS = [
Cards\RevenueCard::class,
Actions\ApproveAction::class,
Dashboards\Overview::class,
];
}The base builds each class once, with the module as its only constructor argument, and the root alone: asking a module for its namespace or its root never builds the rest. Order in ARTIFACTS carries no meaning. A module lists its artifacts unconditionally — what only some users may see is a matter of #[Access], not of the module.
Ui5ModuleInterface reads that declaration back:
| Method | Returns |
|---|---|
getNamespace() | the module's namespace (derived from the root artifact) |
getArtifactRoot() | the root — the App or the Library |
get(Contract::class) | the module's artifacts of one kind, e.g. get(Ui5ActionInterface::class) |
getAllArtifacts() | the root plus every other artifact |
getSourceStrategy() | how and from where the module's UI5 sources resolve |
requiresAuth() | whether the module requires an authenticated user |
A module without a root — or with a second one in ARTIFACTS — fails when the registry loads it, naming the module.
Registration of Subordinate Artifacts
Subordinate artifacts must be explicitly registered: their class goes into the module's ARTIFACTS. LaravelUi5 does not auto-register artifacts, and the generators never edit your module; each ui5:* generator closes by naming the line to add:
Register it in OffersModule::ARTIFACTS:
\Acme\Offers\Cards\RevenueCard::class,
…and list it in the owning Dashboard Group's getChildNamespaces():
'com.acme.offers.cards.revenue',The second half appears for dashboard children only (cards, tiles, charts). A dashboard group is the one exception: it is not registered on the module but composed into a dashboard's getGroups(), and its generator says so.
This keeps module structure under the developer's control and deterministic at runtime — an artifact exists only if it's intentionally exposed.
Module Registration
Business modules are declared in config/ui5.php under modules — a flat list of class strings:
'modules' => [
\Acme\Sales\SalesModule::class,
\Acme\Portal\PortalModule::class,
],LaravelUi5 instantiates each and keys it by its getNamespace(). The namespace is the URL coordinate (dots → slashes) — there is no separate slug to assign. (Infrastructure modules — e.g. the SDK's auth and core modules — register themselves via the infrastructure marker; only business modules go in this list.)
⚠️ No automatic scanning. Explicit declaration keeps the system deterministic and deployment-friendly.
Summary
- A
Ui5Moduleis a container, not an artifact — the structural root for one domain's UI5 backend and frontend. - It wraps an application or a library — never both.
- It is namespace-keyed; the namespace is owned by the root artifact and derived by the module (one source of truth).
- Only app modules define subordinate artifacts, and registration is explicit.
- Business modules are listed (class-only) in
config/ui5.php; the namespace is the URL coordinate.