Ability to manage dependencies between client extensions to ensure a correct deployment order

What is the problem you are trying to solve?

Client Extensions currently lack a native mechanism to define runtime dependencies or load orders. Consequently, the OSGi container starts them without a guaranteed sequence, which causes failures for extensions that rely on one another.

What is your project about? (e. g. Intranet, Partner Portal, Enterprise Website, etc.)

Enterprise Website

What is your proposed solution? (optional)

  1. Introduce a configuration property within the client-extension.yaml file that allows developers to explicitly declare inter-extension dependencies. This would ensure Liferay’s OSGi container honors the correct startup sequence both during deployment and upon server restarts.
  2. Business Value: Removes the need for fragile CI/CD deployment delays and ensures stable, predictable startup behavior for complex Client Extension architectures.

@Timea_Bihari Could you please elaborate on the specific use case driving the need for one Client Extension to depend on another? Understanding the underlying scenario would help us assess whether a new dependency mechanism is the right solution or whether existing patterns already cover it.

For frontend Client Extensions in particular, I’d recommend using a JS Importmap to manage shared dependencies, with the Importmap deployed first as a standing rule. This approach reliably resolves most inter-extension dependency cases without introducing additional configuration complexity.

Thanks
Priyank Gajera

Recommended deployment approach for site initializers:

  1. Deploy foundational client extensions first — ThemeCSS, Favicon, and Global JS client extensions should be deployed before site initializers, since site initializers typically depend on these as baseline assets.

  2. Deploy site initializers last — When promoting to production or upper environments, deploy all other modules first, then deploy site initializers as the final step.

  3. Temporarily disable site initializers when needed — Renaming client-extension.yaml to _client-extension.yaml will prevent a site initializer from executing during deployment.

Important clarifications:

  • Once deployed correctly in upper environments, this is generally a one-time setup process and the race condition should not recur — including after server restarts. We have observed deployments with multiple React client extensions, ThemeCSS, Favicon, and Global JS alongside site initializers without encountering this issue post-initial deployment.

  • Site initializers work best as a one-time site bootstrap. Using them as part of a continuous deployment workflow is not recommended for content-heavy pages, particularly in upper environments where that content is modified by users through the UI. In such cases, re-running the site initializer will overwrite those pages and any UI-driven changes will be lost.

Please let us know if this addresses your scenario, or if there are specific aspects of your deployment workflow where these patterns don’t fully resolve the issue.

Hi Priyank!

This request came through the customer support portal from us. I’ll try to describe the use case that lead to this. We are currently looking into moving as much as possible of our existing stuff over to client extensions, and for this we want to be able to roll out developer environments, test systems, etc. without having to rely on, somewhat weak, scripts or ci/cd to roll out new systems.

The reason we need dependencies or a way of ordering the start of client extensions runtime, is because we have a growing collection of font-end extensions, in addition to several site initializers (created as extinsions, not osgi modules) that rely on some of the extensions (specifically themeCSS and globalCSS seem to be problematic). After an initial full deploy, the site initializers trigger immediately and tend to run before the client extensions have started, leaving the sites in a broken state. The only way to handle this is to first deploy all of the non-site initializer extensions, ensure they have all started, and then finally deploy the site initializers, either through ci/cd or scripts for local deploys.