Customer Success Story: OpenMRS
The Situation
OpenMRS, an open-source medical records platform with commercial distributions, was in the process of transitioning from a singular frontend to a modular architecture. A proof of concept (PoC) had been developed using the single-spa framework, and some core modules had already been ported to the new architecture. The vision was to create an open ecosystem where anyone could contribute their own modules, enabling a flexible and scalable platform.
The Problem
The chosen pattern of a modular system architecture provided a number of benefits, but some key requirements and challenges still needed to be addressed:
- Centralized Control: Previously, new teams had to be registered and managed centrally, limiting the flexibility and scalability of development.
- Lack of Independent Deployments: Teams couldn't deploy their modules independently, in order to avoid slowing down development cycles.
- Performance Issues: The aim was to achieve at least the same performance with the new modular system as with the previous monolithic application.
- Offline Capability: A critical requirement for field workers in remote areas is that the platform offers the ability to function offline.
- Inconsistent Design and UX: The platform needs to offer a cohesive user experience across different modules.
Our Solution
We worked closely with OpenMRS to fulfill these requirements and deliver a scalable, performant solution that met the needs of both developers and end users. Our contributions included:
- Developer Guidance: We provided mentorship and guidance to existing developers to help them adapt to the new modular architecture.
- Onboarding New Teams: We facilitated the onboarding of new development teams, ensuring they could quickly contribute their own modules.
- Independent Deployments: We introduced a new deployment concept that allowed teams to deploy their modules independently, enhancing development agility.
- Refined Architecture: While retaining the core foundation of single-spa and SystemJS for micro frontends, we introduced module federation to manage distributed dependencies more effectively.
- Offline Capability: We added offline functionality, enabling the platform to support field workers in remote areas where internet access is unreliable, such as rural Kenya.
- Performance Improvements: By optimizing the architecture, we ensured the new modular platform performed at least as well as the previous monolithic application.
- Design System Implementation: We led the initiative to decide on a cohesive design system, ensuring a consistent user experience across all modules.
Architecture
With the previously described solution the following architecture diagram was derived:
The app shell (1) itself is developed in a monorepo, together with other relevant libraries. To distribute the app shell, as well as the relevant libraries, the npm package manager is used. This way, the app shell can be just installed (and updated) in projects developing a micro frontend.
The micro frontends (2) are also published to the public npm registry. While alternative methods of distribution are possible, the npm registry (3) allows a couple of interesting things. Most importantly, this allows us to specify the installation source of a micro frontend inside the distribution manifest (4) via simple names instead of full URLs.
For local development the distribution manifest can be just swapped from the command line. In the local dev mode (5) the remote micro frontend sources are replaced by local sources. Of course, this approach can be combined with a distribution manifest - loading remote micro frontends together with one or more local micro frontends.
The distributed resources bring a couple of assets and properties with them (6). Most importantly, they can included instructions for the offline mode, translations of the texts seen on the screen, all the designs, as well as the possiblity to be reconfigured as needed.
In the end all declared components, pages etc. including their assets and functions are consumed via the contained micro frontend resources (7) or in the core SPA layer (8). The main difference between these two is the cache treatment. The main one comes with the centralized cache handler, while the micro frontend resources use individual handlers.
The Outcome
The modular architecture we helped build became the standard for the OpenMRS ecosystem, culminating in its release with OpenMRS 3. The platform now features offline capabilities, which are critical for field workers in countries like Kenya, allowing them to continue their work without disruption. Dozens of modules have been developed and are available from the core team, providing flexibility for commercial distributions and ensuring a thriving, open ecosystem.
By solving the initial challenges and delivering a scalable, independent deployment model, OpenMRS is now well-positioned to continue growing as an open-source leader in global healthcare.