Case Study

Turning OpenEMR Forms Into a Configurable Forms Engine

Replacing form-by-form OpenEMR development with a configuration-driven Forms Engine

  • Healthcare
  • OpenEMR Engineering
  • JSON
  • MySQL
  • OpenEMR
  • PHP

OpenEMR ships with a lot of clinical functionality, but every organization eventually needs forms it does not have. On this project, the request was not for one more form. It was for a way to stop building each form as its own development project. Ayeim designed and implemented a configurable Forms Engine inside OpenEMR: clinic administrators create and change forms through a user interface, and the form definition is held as configuration rather than as code.

The challenge

The question the clinic was really asking was not “how do we create another OpenEMR form?” It was “how can staff create and manage different forms without a developer building new files and database structures every time?”

Adding a custom form to OpenEMR the traditional way tends to involve dedicated PHP files, a dedicated table, fields defined in code, validation logic written by hand, and changes to the database structure. Each form is a small, self-contained piece of application code that then has to be deployed and maintained.

Why the existing approach did not scale

That pattern works for a handful of forms. It gets heavier as the count grows:

  • The same development steps are repeated for every new form.
  • There are more files and more tables to keep track of.
  • Every form change is a deployment.
  • Changing a form after it is live means going back into code.
  • Implementations drift apart, because each one is written separately.
  • The clinic depends on a developer for changes that are, in substance, configuration.

None of this is catastrophic on its own. Together, over time, it is the kind of complexity that quietly slows an organization down.

The Ayeim approach

Rather than build the next form, Ayeim built the thing that builds forms. The Forms Engine treats a form’s structure as configurable data. An administrator working in the OpenEMR environment can:

  • Create a new form and give it a name.
  • Add fields and set their properties and types.
  • Arrange and reorder fields.
  • Change a field’s configuration later without touching source code.
  • Decide whether the form should show historical responses.
  • Save the form — no new PHP file, no new table.

The objective was narrow and deliberate: move the part of a form that is genuinely configuration — its fields, their order, their properties — out of source code and into a controlled administrative interface, while leaving everything that should stay in engineering hands where it is.

How the Forms Engine works

An administrator defines a form and its fields in the Forms Engine UI. The engine serializes that definition and stores it in the database as JSON. When the form is opened, the engine reads the definition and renders the form dynamically from it. Submitted data is captured against that form, and whether previous responses are shown is governed by the form’s own configuration.

JSON is used here to represent the configurable structure of a form, so that a new form does not require a new database schema. It is a description of how the form is built, not a dumping ground for clinical data. Form configuration and form responses are treated as two different things.

Clinic administrator
Forms Engine UIdefine form and fields
JSON form definitionstored in the database
Dynamic form enginerenders and captures
OpenEMR clinical workflow

Configurable form architecture

The important idea is a change of category. In the traditional approach, form structure is custom code. In the Forms Engine, form structure is configuration.

Field definitions are configured rather than hardcoded — properties such as label, type, whether the field is required, ordering and field-specific options are set through the interface. The set of configurable properties is bounded by what the engine supports; it is not an open-ended form builder, and it is not meant to be. It is an OpenEMR-focused capability that works inside the clinic’s existing authentication, authorization and workflow.

Form history

One specific requirement was control over historical form information. Some forms benefit from showing previous entries — a recurring assessment where the last few results matter. Others should only ever show the current interaction.

The Forms Engine makes this a configurable behaviour rather than a fixed rule. The form’s configuration determines whether it shows historical entries, shows only the current interaction, or retrieves previous responses where that applies. History is not switched on for every form by default; the administrator decides per form. That gives clinics more control over how recurring forms and longitudinal information are handled.

Before vs after

Before — custom form development

  • Developer-dependent for every form
  • Form-specific PHP files
  • Form-specific database structures
  • The same implementation repeated
  • More maintenance points as forms are added

After — configuration-driven Forms Engine

  • Administrator-managed configuration
  • One reusable form engine
  • JSON-based form definitions
  • Dynamic rendering from the definition
  • Configurable history behaviour
  • A single, central place for form logic

Complex or unusual requirements can still need engineering support. The change is that routine form work no longer does.

The engineering decision: from custom forms to a forms platform

The project turned on a fairly simple observation. When the same development pattern keeps repeating, the answer is often not another implementation of it — it is an abstraction over it.

Repeated custom forms pointed to a missing layer: a reusable engine that treats a form definition as configuration and renders it at runtime. Building that engine once removed the need to treat each subsequent form as a separate development exercise, and left a foundation that further form requirements can be met against by configuration.

The result

The outcome was a shift from form-by-form development to a reusable, configuration-driven approach:

  • Forms can be created and managed through an administrative UI.
  • Field configuration is handled without editing form source code for every new form.
  • Form definitions are stored as JSON configuration in the database.
  • One engine supports multiple forms.
  • Whether a form displays historical responses is configurable.
  • The architecture is a reusable foundation for future OpenEMR form requirements, rather than a one-off.

Business value

Healthcare organizations change their workflows over time, and forms change with them. A configurable Forms Engine means most of those changes are configuration, not a software project:

  • More configuration, less repetitive custom development. Adding or adjusting a form is an administrative task, not a release.
  • More reuse, less duplicated implementation. One engine instead of one implementation per form.
  • Centralised form logic, easier long-term maintenance. Fewer places for behaviour to diverge.
  • Administrator control, less dependency on developers for every change. Engineering is still there for the hard cases — it is just no longer on the critical path for routine ones.

The important part of this project was not creating one more OpenEMR form. It was recognizing that repeatedly creating forms was the problem. Once that was clear, the form definition moved from code into configuration and an engine was built around it — which changed the question from “how do we build the next form?” to “how do we configure the next form?”

Capabilities

OpenEMR engineering, healthcare technology, software architecture, configuration-driven system design, database design, dynamic application design and workflow modernization — with long-term maintainability as the goal rather than a one-time deliverable.

Related OpenEMR services

How this connects

Where this work fits in what Ayeim does

Next step

Have an OpenEMR workflow that still depends on custom code for every change?

Let's look at whether a configurable approach could simplify it.