Skip to Content
DocsRecipesCreate a frontend module

Creating a frontend module

OpenMRS publishes @openmrs/create-o3-app, a generator for scaffolding O3 frontend modules. Module authors should run it through npm’s create initializer as npm create @openmrs/o3-app@latest. The generator source lives in openmrs/create-o3-app, and the Template  frontend module remains useful as a reference for the generated structure.

Always include the @openmrs/ scope. The unscoped create-o3-app package on npm is an unrelated third-party project, so commands such as npx create-o3-app ... fetch the wrong tool. Use npm create @openmrs/o3-app@latest ... or npx @openmrs/create-o3-app@latest ....

Prerequisites

  • Node.js 20 or newer.
  • Corepack enabled, so the generated project’s pinned Yarn version works without a separate Yarn install. If Corepack is not enabled yet, run corepack enable once.

Quick start

Run the generator from the directory where the new module folder should be created:

npm create @openmrs/o3-app@latest active-prescriptions

This creates a standalone page module using the CLI defaults. In directories where the CLI detects an existing monorepo, it may ask whether to add the module to that monorepo. If npm create is not your habit, the equivalent scoped npx command is:

npx @openmrs/create-o3-app@latest active-prescriptions

Example: active prescriptions

Suppose you want to create a frontend module that provides a UI for displaying active prescriptions. Our goal is to recreate the Active Prescriptions tab from openmrs-esm-dispensing-app.

Scaffold the module

For a repeatable, CI-friendly command, pass explicit flags after npm’s -- separator:

npm create @openmrs/o3-app@latest active-prescriptions -- \ --standalone \ --package-name "@openmrs/esm-active-prescriptions-app" \ --route "/active-prescriptions" \ --route-component "ActivePrescriptions" \ --no-git \ --quiet

The -- separator is required when forwarding flags through npm create. Rspack is the default build tool; add --webpack only if you specifically need a Webpack scaffold.

ℹ️

Why the esm prefix? Frontend modules conventionally use package names that start with esm. See the frontend modules overview.

Run it locally

The generated directory is based on the package name. For the command above, enter the generated project and start the local O3 shell:

cd openmrs-esm-active-prescriptions-app corepack yarn install corepack yarn start

For standalone modules, the CLI installs dependencies automatically unless installation is skipped, interrupted, or you used --dry-run, but running corepack yarn install is safe when you are checking out or resuming a generated project. The app should be available at http://localhost:8080/openmrs/spa/active-prescriptions. Use username admin and password Admin123 for the default development backend.

Use corepack yarn start --port <port> for a different port. Use corepack yarn start --backend <url> to point the development shell at another OpenMRS backend, such as corepack yarn start --backend http://localhost.

Customize the generated files

Review the files most modules change first:

  • src/constants.ts exports the package moduleName.
  • src/routes.json registers pages and extensions with the app shell.
  • src/config-schema.ts defines runtime configuration.
  • src/active-prescriptions.component.tsx is the generated page component.
  • translations/en.json contains the starter translation strings.

The generated module also includes src/index.ts, src/root.component.tsx, the selected build config (rspack.config.js by default), a starter src/root.component.test.tsx, Vitest with jsdom, ESLint, Prettier, Husky, and translation extraction wiring. src/routes.json maps the /active-prescriptions route to the exported root lifecycle, and root.component.tsx renders the route component. If you generate a module with extensions, the same template pattern creates extension component files and exports their lifecycles from src/index.ts.

Preview before writing files

Use --dry-run to see what would be created without writing files, installing dependencies, or initializing Git:

npm create @openmrs/o3-app@latest active-prescriptions -- --dry-run

Common flags

FlagUse
--standaloneCreate a standalone module, which is the default outside a detected monorepo.
--monorepoAdd a module to the current monorepo and use the default package path.
--new-monorepoCreate a new monorepo root with this module as its first package.
--package-name <name>Set the npm package name, such as @openmrs/esm-active-prescriptions-app.
--route <route>Set the route path for a page module. Use it with --route-component.
--route-component <name>Set the React component name for the page route. Use it with --route.
--webpackUse Webpack instead of the default Rspack build config.
--no-gitSkip Git initialization.
--no-ciReserved for generated CI workflow support. The current template accepts the flag but does not emit workflow files yet.
--dry-runPreview generated files without writing them.
--quietSuppress output and use defaults where possible.
--verbosePrint more detailed output.

--rspack exists only as a deprecated compatibility flag because Rspack is already the default.

Monorepos

Existing monorepo

From the monorepo root, run:

npm create @openmrs/o3-app@latest referrals-queue -- --monorepo

The CLI uses the default package path packages/apps/esm-referrals-queue and updates the workspace configuration when it detects a supported workspace file.

New monorepo

To create a new monorepo root with the generated module as its first package, run:

npm create @openmrs/o3-app@latest referrals-workspace -- --new-monorepo

The CLI creates the root project and places the module under packages/apps/esm-referrals-workspace.

Publishing and adding to a distribution

Once the frontend module is ready, publish the package to npm. The package should then be visible on npmjs.com, such as @openmrs/esm-login-app.

To include the module in a distribution, add it to the frontendModules object in the distribution’s spa-assemble-config.json file:

spa-assemble-config.json
{ "frontendModules": { "@openmrs/esm-active-prescriptions-app": "1.0.0" } }

Use a tested version for release distributions. For more information, see the Creating a distribution guide and the Configuration overview guide.

Last updated on