Wiki Spaces


Get Help from Others

Q&A: Ask OpenMRS
Discussion: OpenMRS Talk
Real-Time: IRC Chat | Slack


Page tree

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.

This documentation is intended to enable administrators, implementers, and developers to set up and configure an OpenMRS Frontend 3.0 application (aka 3.x, aka O3).

If you haven't seen the O3 Project Overview yet, do that first.

titleNotes For Developers

In This Guide: 

Table of Contents

  • Exclamation Question Mark Emoji Still confused? Try using the search bar in the Dev Guide to search for a key term:
  • If you still can't find what you need, please reach out to our 3.x squad on this slack channel: #openmrs-helpme
  • We'd also love to hear from you any suggestions on how to improve this guide!


Two Important Qualities of the OpenMRS 3 Frontend

The OpenMRS 3 Frontend has two important qualities:

  • It can be served independently of the OpenMRS server itself. It is just static files, and you can use any web server to serve them. They will communicate with the OpenMRS server via network requests (REST, FHIR, etc).
  • The frontend modules come together to form the application on the client's computer. This means that the modules can be served independently of the base frontend application.

What is a Frontend Module?

OpenMRS Frontend 3.0 uses frontend modules. A frontend module is a self-contained piece of application. It has some UI, and some ideas about where in the application it should be rendered. Each frontend module can be configured and some aspects of how frontend modules interact can be configured, too.

Important Pieces of the O3 frontend modules system 

There are four important pieces of the OpenMRS 3 frontend module system:

  • The app shell, which is the "base" of the application and coordinates everything
  • The framework, which is a shared library that all frontend modules use
  • The import map, which is a file that tells the app shell what frontend modules to use and where they are
  • The frontend modules, from which the interface is composed


Feeling confused about the pieces of 3.x?

A visual map of building a 3.x application is described in more detail in the Dev Guide's Map of the Project.


Each frontend module is an NPM package with a name ending in -app. Examples shown in the examples below: (Click to expand)


Reference Docker Containers

Reference Application Docker containers are available here: 

titleLooking for a docker-compose file?

OpenMRS 3.x is a WIP and is not yet formally released. However, to get a relatively recent version of 3.x running using Docker, you can use this Docker Compose file. (This file will also share some documentation about the docker images.) 

Note: you should rename the file ‘docker-compose.yml’, so that you can run docker-compose up  to start all the containers docker instance. Previously a .env file was needed. We are fixing that issue as of Mar 4 2022, though we’d strongly recommend people use a .env file. The .env file provides key-value pairs of environment variables, in this case, the user name and password for the database.

We are also going to be updating the central OpenMRS SDK docker-compose files so that it has the 3.x docker compose information needed. This will allow current OpenMRS organizations to deploy 3.x with their implementation using the OpenMRS SDK. 

Part 1: Build and Deploy the OpenMRS 3 Frontend

Step 1: Choose your install / serve path

There are several ways to deploy the OpenMRS 3 Frontend, depending on your needs and technical capabilities. Here we will cover 2 options–deploying the frontend using Tomcat and the OpenMRS WAR or deploying the frontend using nginx: 

  • Option 1: OpenMRS Server: Install using OpenMRS tooling + Apache Tomcat. In this case, you will build and assemble using the OpenMRS SDK and served from the OpenMRS server itself using the OpenMRS SPA Module. This is the simplest kind of deployment. Implementations with many Java-familiar team members, who know Tomcat inside and out, may strongly prefer this approach. This also simplifies your architecture as there is only one server involved.
    • Example distribution using this approach: Palladium
  • Option 2: Web Server: Serve the frontend using nginx, Apache server etc. This approach enforces separation from the backend; the frontend runs completely independently. This ensures that your frontend will run regardless of whether the backend stops sucessfully, etc.Teams concerned about load balancing may prefer this approach. (Of course, if the backend fails, you won't be able to use the frontend client, but the separation between frontend and backend gives you a way to communicate tothe user that there is something wrong with the backend. Whereas for users using the OpenMRS server/Tomcat approach, their system might be entirely inaccessible.) 
    • Example distribution using this approach: AMPATH

Step 2: Add Essential Modules

The following modules are essential to run the O3 frontend (note: if these modules are new to you, just install the latest version of each).

  1. FHIR2 Module (1.2.2+)
  2. REST Module (2.24.0+)
  3. SPA Module (1.0.8+) (only required if you want to serve from Tomcat; not needed for the nginx approach)
  4. ID Gen (4.6.0+)

These are the key to communication with your existing OpenMRS backend. Add these modules to your environment (i.e. your existing implementation). 

Step 3: Assemble, Build, and Serve

There are 2 ways of building the frontend: 

  1. Run mvn openmrs-sdk:build-distro with a file

  2. Use the npx openmrs build and npx openmrs assemble commands.

Below we will give some additional guidance depending on your Server choice; however, both of these above approaches are valid for either method of deployment.

It's where the files get served from that we branch this guide (based on your decision to use an OpenMRS Server or a Web Server). 

Time to choose your own adventure: OpenMRS Server Option  OR  Web Server Option

Reminder: Your "Import Map" specifies which apps you will have. In this step you will specify the versions and configuration you want from your import map. 

titleA Note on Versions

OpenMRS ESMs are released with three different tags: "next", "latest", and a version number. The version number always refers to a specific build of each ESM, e.g., 3.2.0 or 3.2.1-pre.1067 are both specific versions of the @openmrs/esm-api ESM, though the latter is a pre-release version. "latest" always refers to the most recent released version of an ESM (e.g., 3.2.0). "next" always refers to the most recent pre-release version of an ESM (e.g., 3.2.1-pre.1067). While you are free to go with the "latest" version of any ESM, you may wish to have more control by specifying the exact version number of each ESM you use.

OpenMRS Server Option

3.1: Building with the SPA Module

First, assemble your import map + assets (See Customizing the Import Map if you're still confused.) You'll use tooling to run the assemble command, and you'll provide basic config like the apiURL, spaPath. 

The OpenMRS SPA Module serves the application from the  <server_dir>/frontend/ directory.

  1. Move the SPA Module into the frontend directory. The OpenMRS SDK will build the Frontend 3.0 application in the frontend/ directory within the server directory when the distro file contains any frontend modules. The Frontend 3.0 application is installed when  openmrs-sdk:install, openmrs-sdk:deploy, or openmrs-sdk:build-distro are executed. For an example of how to add frontend modules to the distro file, see the file for Reference Application 3.x.

Frontend modules should be specified in the file in the following format:


<version> can be any version number or any tag published for that package in npmjs.

The other properties accepted by the OpenMRS SDK for the frontend application are


These are described in the frontend tool help documentation. Execute

npx openmrs@next --help
npx openmrs@next build --help

to read more about them. You will need to have NPM installed as well as the frontend tool ( npm install -g openmrs ).

You should wind up with the file  <server_dir>/frontend/index.html , alongside directories with the names of the microfrontends you are using. When you run your server, you should be able to access your application at /openmrs/spa/login , assuming you have included @openmrs/esm-login-app .

3.2: Serve step: SPA Module Route

Once you have your application files together, you will need to serve them from somewhere. You can technically serve them from anywhere—from a simple file server or a docker container.

One option is to serve these files using the OpenMRS server itself, using the OpenMRS SPA Module. Here's how to use this option to serve a frontend application that you have built:

Install the SPA module as you'd install any other module. Then drop your OpenMRS Frontend 3.0 application files into <server_dir>/frontend , where <server_dir>  is the application data directory. So on an SDK server called "narnia" on a *nix computer, you would put the files in  ~/openmrs/narnia/frontend/ . On a Tomcat server, the files would go in  ~tomcat7/.OpenMRS/frontend/  . If you then start this server on port 8080 and navigate to http://localhost:8080/openmrs/spa/login , the SPA Module will attempt to serve the file at  frontend/index.html . The "login" part of the path doesn't matter—in a SPA like OpenMRS Frontend 3.0, the  index.html  file is always served, and handling the specific route is left to the application itself.


See this implementer’s real-world example on GitHub here

Web Server Option

3.1: Building and assembling the application using the build tool

First, assemble your import map + assets (See Customizing the Import Map if you're still confused.) You'll use tooling to run the assemble command, and you'll provide basic config like the apiURL, spaPath. 

Note: If you’re serving using nginx: have an nginx config. If using docker: make sure to move things into the correct directories for nginx.

You do not need to use the SDK to build the frontend application. This may be preferable if you want to build the frontend application separately from your SDK build/deploy tasks. To do this, use the frontend tooling, npx openmrs , directly. This is the same tooling as used by the SDK, described above. The resulting files can be served from any file server, or from the OpenMRS server itself (as described above).

The following command will build the app shell. This includes the framework, as well as the index.html file which will serve as the entrypoint to your application.

npx openmrs build

Remember that many commands will provide helpful information when run with the --help flag. The various features of npx openmrs offer command line flags that you can use to get the application set up according to your needs. Try the following command, for example:

npx openmrs build --help

At this point we still need an import map and the frontend modules. In most cases, we will want to package the whole application and serve it together. We can assemble an import map and frontend modules using the following command:

npx openmrs assemble

At this point, you should have an application that you can serve.

3.2: Serve step: Serving frontend modules from a nginx

Once you have your application files together, you will need to serve them from somewhere. You can technically serve them from anywhere—from a simple file server or a docker container. The easy solution here is to move the files into the nginx webroot (this is set in the nginx.conf file and usually points to /var/www/html on Linux). 

Since the frontend modules of the application come together on the client, they do not necessarily need to be packaged with the app shell. This can be an advantageous setup if you want to be able to deploy updates to frontend modules without having to modify files on the server itself.

To do this, you will need to assemble your import map manually. Run  npx openmrs assemble   and look at the resulting  import-map.json   file so that you have an idea of what the import map should generally look like. The entries of your import map, however, will have values that refer to remote places where the package is served. An example line might be

"@openmrs/esm-login-app": ""

Note that you should not use unpkg as your CDN; it is a free service which provides no uptime or support guarantees.


You may be tempted to import all possible OpenMRS esms into your import map, but the outcome may cause a rendering mess.

We recommend referencing the default assemble / list of esm modules listed in the 3.x Reference Application here.

Step 4: Check your backend dependencies using the O3 Implementer Tools

  1. Go to your O3 environment and sign-in as a system administrator.
  2. Click the Implementer Tools icon to open the implementer tools (only visible to Admin users).  
  3. Click the tab called Backend Modules
  4. Scroll through the list to see the Required Version of your modules to adequately support your O3 interface. 

Step 5: Celebrate! (star)

We'd love to hear from you if you successfully set up O3. Please share your success with us by posting on that you were successful. And if you ran into any issues, please share those, and feel free to update this documentation!

Example Distribution

To create an example distribution using the OpenMRS 3.0 SPA as frontend you'll need to think of three things:

  1. The app shell (namely what settings you'll need to include it)
  2. What frontend modules to include (their names and versions)
  3. The configuration for these frontend modules

The parts of (2) and (3) also flow in directly or indirectly into the settings defined for (1).

Let's start with (1):

Code Block
  npx openmrs build --spa-path /openmrs/spa/ --api-url /openmrs/ --config-url config.json --importmap importmap.json

Using this command you'll build a new app shell that will be placed at /openmrs/spa/. The OpenMRS API is supposed to be on the same server (at least reachable from the browser) at /openmrs/ (e.g., a call to /openmrs/ws/rest/v1/session yields the session, so /ws is rooted at /openmrs).

The command above also defines two more things: The frontend modules from (3) are determined by an importmap.json which will be available in the same directory as the SPA (i.e., reachable at /openmrs/spa/ from the browser). Likewise, a configuration file is specified; the file config.json will be loaded from the SPA's path, too.

Now that you'll have your files for the app shell its time to look at how to get the remaining ones.

The frontend modules from (2) can be assembled using:

Code Block
  npx openmrs assemble --mode survey

This will run a command-line survey iterating over all (publicly) available frontend modules. If included, the survey will ask you what version to take.

Once completed, you'll have a valid importmap.json as well as a directory with all files corresponding to the different frontend modules referenced in this importmap.json.

Finally, you'll also need a configuration. Ideally, you can just write some JSON that represents such a configuration, however, in the real world this will not be so easy.

Our recommended approach is to actually start with an empty JSON file just containing {}. With this empty configuration you can fire up your application shell and actually set it all up as you want to. The frontend module @openmrs/esm-implementer-tools-app will help you to do exactly that.

When you completed your customization in the frontend you can download your individual config.json. Now you can put it besides all the other files to complete your own distribution.

Known Issues

  • FHIR and FHIR2 clash on older Platform versions (2.0-2.3.x): Platform versions 2.0.0-2.3.x came with the old FHIR module (v1) pre-bundled. FHIR2 wasn’t bundled until Platform 2.4. Adding the new FHIR2 OMOD while using one of these older platform versions conflicts with the bundled v1 FHIR module. If your Platform version is still running the original FHIR module,remove that module and install the FHIR2 module. Talk Thread for more details and questions here
  • Cohort Module version <=3.0.0-SNAPSHOT can break the application when deployed withopenmrs-module-emrapi: There is a fix for the Cohort Module that fixes this. See this talk thread for details. 
  • SQL issues when using the Initializer module: Apparently these can begin to challenge each other. More information to come. We suspect the initializer module and other modules that insert data needs to update/insert instead of just inserting data.
  • npx openmrs build fails on npx version 8.*.?. Current working build uses npx version 6.14.15, node v16.13.0
  • FHIR module liquibase error on 1.3.0 - Deploying v1.2.1 and then updating sequentially to 1.3.0 should run migrations needed and solve the issue.
  • See Also: O3 Dev Docs FAQs

Part 2: Configure Your O3 Application

What an OpenMRS 3 frontend configuration file looks like

OpenMRS 3 frontend configuration files are JSON files containing module names as top-level elements. All configuration elements are optional. The available configuration elements for each module should be documented in the module’s wiki page or README file.

Here’s an example:

Code Block
titleShort Example
  "@openmrs/esm-login-app": {
    "logo": {
      "src": ""
  "@openmrs/esm-home-app": {
    "buttons": {
      "enabled": false

Alternatively you can provide your config file as a JavaScript file. It will look just about the same, but with some magic words at the beginning:

Code Block
titleShort Example - JS
exports = {};
exports.default = {
  "@openmrs/esm-login-app": {
    logo: {
      src: ""
  "@openmrs/esm-home-app": {
    buttons: {
      enabled: false

How to configure your OpenMRS 3 implementation

You can pass  --config-url  parameters to the build tool  npx openmrs build.

The following command will build an application that looks for config files at the URLs  /openmrs/spa/abc/config.json  and :

 npx openmrs build --config-url abc/config.json --config-url

Config files will be merged, with values from subsequent files overriding those coming previously. For example, if  abc/config.json  has contents

  "@openmrs/esm-login-app": {
    "logo": {
      "src": "",
"alt": "Our beautiful logo" } }

and  has contents

"@openmrs/esm-login-app": {
"logo": {
"alt": "Our all-star logo"

Then the login page will display the logo given by the first config and the alt text given by the second config.

In this way, you can break up your configuration files into hierarchies, per module, per groups of modules, or however else you please.

See  npx openmrs build --help .

Configure your Branding

you can configure your branding as desired. For example if you want to change the color of your theme to that of your organization, bellow are the steps !

  • Click the settings icon that opens up the different configurable options.
  • Choose (esm-styleguide) on the configuration options,this comes with different editable color codes.
  • You can change the color codes to your desired ones.
  • Save your changes ie around the color code there is an icon of saving that always appears after editing the color code.
  • Checkout out your changes from the application interface!

NOTE: The Different sections of the application can be changed to different colors  under the configurable option (esm-styleguide),enjoy.



O3 Branding Tutorial

Widget Connector

Configure the Patient Chart Navigation: Pages & Dashboards

you can configure the patient chart navigation by adding an extension slot to the configurable json file of the patient chart.

This is achieved  by opening up the implementor tools on clicking the setting icon and then switching on the json editor.At this point you can add an extension slot to the patient chart navigation json file.

Code Block
titleCode exampleShort code

               "title":"HIV Adult Return",
            "title":"NCD Outpatient",

Have you developed a configurable extension? Please consider making a similar video to showcase how to do the configuration, and share your video on our Talk Forum! This will create a library of widgets for us to showcase. 


O3 Patient Chart Configuration: Tutorial Part 1

Intro and Configuration of a Nav Group

Widget Connector

Configure your First Widget

This can be achieved by adding an extension named (obs-by-encounter-widget) to the json configuration file

Code Block
titleCode exampleShort code
            "title":"HIV Widget",
                  "label":"Viral load",


O3 Configuration: Tutorial Part 2

Add a configurable obs-by-encounter widget

Widget Connector

Configure the Layout of a Chart Page

Coming Soon

Part 3: More Advanced Configuration

Configuring O3 Forms

Configuring your Metadata

We highly recommend using Initializer to set up your config. Example 3.x RefApp Configuration folders that are consumed by Initializer can be found here

Step-by-step documentation on setting up sites with OCL-created concepts via Iniz is here (this is especially helpful is you need to roll-out at many offline sites).

Configure the Lab Filter feature

The Lab Filter feature enables you to set up custom filter views - eg based on standard medical hierarchies, or even based on your own custom ideas (e.g. "Our Favorite HIV-Related Tests"), like this:


To set up your own preferred Filters and Test Hierarchies, follow the steps in the esm-patient-test-results-app README here

Add full feature sets with OMRS Packages

Packages will be added through a build step, e.g., by running the SDK’s build-distro command. This functionality is yet to be built. More detail coming soon.