All articles

B2B App Delivery Models Unpacked

Introduction

In this article, we are going to talk about how to build a successful delivery strategy using Jmix. Once you decide to start a new project with Jmix, you need to think about how you will deliver value to your customers in the most effective way. Failing this milestone at the very beginning can easily break the whole project when you start scaling and maintaining it. Let’s see how it may happen with the story of Ben.

seasoned software engineer who one day decided to create his product and found himself quite successful

Ben’s Story

There is nothing unusual about Ben’s story — on the contrary, you might call it typical for our day and age, and many of our readers might find themselves in a similar situation one day. It’s a story of a seasoned software engineer who one day decided to create his product and found himself quite successful at first. He built a risk management app according to some local regulations, found a niche, a market for the product, and acquired his first 10 customers in just 9 months.

At this point Ben achieved positive cash flow, and all seemed well. But then he started to encounter issues that typically arise when users begin to adopt the product, and the number of customization requests increases drastically, each one being individual. You may recognize the situation, especially if you develop B2B applications. In this area, customization requests are very common.

As time goes on, Ben's initial optimism gives way to frustration and burnout — an all-too-common reality in early-stage B2B development.

Frustrated software engineer

What Went Wrong?

The answer is simple: at this stage, each minor logic fix has to be patched across 10 code forks, which leads to implementing 10 risky releases. What’s even worse, whenever Ben finds a bug in the core logic, he needs to fix it in every fork. It also becomes very hard to reuse features across the customer pool and to evolve the product itself. So, there is no room for growth, and all Ben’s time is now spent patching the forks rather than delivering new features to the product’s users.

Why do so many software engineers fall into this trap? Because by default, developers tend to start a new branch for every client. They arrange a dedicated database for each customer and then make changes in those branches, according to requests. As the infrastructure becomes more complex, they switch to fully manual deployment, which slows down progress and makes scaling much harder. We call this type of software development life cycle “Copy, Paste and Pray”.

It may seem trivial from the outside. But if you’ve experienced this situation firsthand, you know how stressful it can become. And this is exactly what we are going to explore below — how to avoid such pitfalls when starting your own digital product. This information is also useful for those who provide multi-client internal systems and are trying to balance customizations and maintainability.

To sum it up, Jmix is a perfect solution for Java/Kotlin teams who:

  • Deliver multi-client, modular, or internal systems
  • Work with limited or no frontend developers
  • Need to balance customization with maintainability

These goals are achieved with the help of three delivery models that Jmix supports out of the box. Let's discuss each of them in detail.

   Ideal for Solution Benefits
Extension model Dev shops Core + Extension Reuse
SaaS model Product teams Multitenant app Scaling
Self-hosted model Regulatory Composite project Control

Core Extension Model

If you're considering Jmix as the platform for your existing or next product, let’s begin with the Core Extension Model.

Jmix applications are built from subsystems—separate modules that encapsulate specific functionality. These can include domain logic, UI screens, roles, integrations, or reusable services. Subsystems are categorized as either core (provided by the Jmix platform, like security, data access, UI) or optional (added on demand, like Reports, BPM, or Multitenancy).

In Jmix terminology, subsystems are typically delivered as add-ons. An add-on is a self-contained functional unit that can be included in multiple projects. Developers can create custom add-ons to share business logic or integrations across teams or clients. The Core Extension Model builds on this modular structure.

You can implement this model in two ways:

  1. Reusable functionality as add-ons: For example, you can create an add-on that retrieves national currency exchange rates. You can then integrate this into multiple projects. If the external API changes, you only update the add-on. All projects that depend on it get updated during the build process.
  2. Application core as an add-on: You develop your core application as an add-on and deliver it to your clients. Each client can extend this core in their own application.
For Client A, you extend this CRM with a Deals module, new UI screens, and custom roles. For Client B, you add a new approval flow and industry-specific dashboards.

Let’s say you’ve built a niche CRM system - with shared entities, business logic, UI, and roles - and packaged it into a reusable core add-on. For Client A, you extend this CRM with a Deals module, new UI screens, and custom roles. For Client B, you add a new approval flow and industry-specific dashboards. Each client has their own Jmix project that depends on the same CRM core, but is extended in a modular and isolated way.

This setup allows you to:

  • Deliver updates to the shared core and detect integration issues at compile time
  • Keep client-specific logic separate and maintainable
  • Delegate product customizations to partners or local teams using the same extension mechanisms

This approach is especially effective when you want to enable third-party developers or regional partners to adapt your product for local industries or compliance needs - without touching the core logic.

SaaS Model

If your customers do not require many customizations and you aim to scale your application efficiently, consider the SaaS (Software as a Service) model. Jmix supports this model out of the box with a free Multitenancy add-on.

In a multitenant model, all customers (tenants) access the same application instance. The Multitenancy add-on allows you to separate data, logic, roles, and permissions by tenant. You can:

  • Use tenant-specific filters
  • Create tenant-specific reports
  • Define dynamic attributes per tenant
  • Customize BPMN workflows per tenant

You can explore a demo of this setup via the Jmix Bookstore application. For a real-world case, take a look at Certikeeper — a SaaS product built entirely with Jmix defaults and launched by a client team as their first product. Thanks to Jmix’s built-in multitenancy support, Certikeeper was delivered with minimal infrastructure and without excessive customization effort.

The SaaS model is ideal for SMB-targeted solutions with standardized workflows. But if you’re selling to banks, energy providers, or public institutions, the centralized infrastructure and limited customization options might not be acceptable.

Self-Hosted & Composite Project Model

For clients in highly regulated industries — such as government, utilities, or banking — who demand full control, a self-hosted delivery model is often required. These customers may ask for complete source code access and expect the application to run in isolated environments, sometimes even offline.

In these scenarios, the product is delivered as a composite project — a Gradle-based setup where the main application includes multiple reusable or custom modules as local dependencies. This setup allows for:

  • Building a dedicated client version from selected modules
  • Customizing and extending features without duplicating the entire codebase
  • Supporting long-term contracts with heavy integrations (e.g., ERP, CRM)

Jmix’s modular architecture allows teams to split functionality into bounded contexts — such as Inventory, Document Flow, or Delivery — and maintain them separately. You can keep a clean shared core and deliver only relevant modules per customer.

Composite builds are especially helpful when delivering code into a customer’s private Git repository. Customers can use Jmix Studio to assemble their own versions of the product, extend certain modules, and manage deployment themselves - all while still benefiting from updates to the core.

Summary Matrix

Criteria Extension model SaaS model Self-hosted model
Multi-client scaling ✅✅ ✅✅✅
Per-client customization ✅✅ ✅✅✅
Code reuse ✅✅ ✅✅✅
Design complexity $ $$ $$$
DevOps complexity $$ $$$ $

Final Thoughts

The Extension Model offers a strong balance of maintainability and customization. It’s ideal when you don’t need massive scale but still need client-specific features.

The SaaS Model works best when your target audience doesn’t require heavy customization and shared infrastructure is acceptable.

The Self-Hosted Model, often combined with the composite project approach, fits regulated or high-control environments and enables modular customization while reducing code duplication.

If you’re not sure which model fits your case, Jmix team can help with architecture design, deployment planning, or training to avoid common mistakes early in the process.

Happy software engineer

Develop smart, not hard! With Jmix!

Jmix is an open-source platform for building enterprise applications in Java