Ballerina is the only integration language built for healthcare. With its native support for healthcare standards like FHIR, HL7, and X12, Ballerina enables rapid health tech application development.

Build with Ballerina and make a difference in the world today.

Download Ballerina

Position Ballerina

Why is Ballerina the way to write healthcare applications?

Java and HAPI have long been the de facto for health app development. However, cloud native healthcare application development goes beyond dealing with objects and frameworks. This domain needs a fresh architecture and technology that treats concepts like FHIR and HL7 as first class citizens in the language, alongside concepts like JSON and APIs.

Ballerina is a language built from ground up for building healthcare applications, quickly, easily and securely. Alongside its powerful integration capabilities, Ballerina natively understands health data standards like FHIR and HL7. It includes FHIR connectors and validators, FHIR API templates, HL7/C-CDA to FHIR data transformations, Capability Statement template, SMART configuration template, EMR connectors, and supports any Implementation Guide with its automatic code and template generation capabilities.

Why is Ballerina the way to write healthcare applications?

FHIR? Ballerina is FHIR

With built-in support for FHIR (Fast Healthcare Interoperability Resources), Ballerina makes it easy to develop and deploy healthcare applications that can exchange and process FHIR resources. Ballerina's native FHIR capabilities enable healthcare developers to build scalable and flexible healthcare solutions that can adapt to changing healthcare needs and standards.

public function main() returns error? {
    // The following example is a simple serialized Patient resource to parse
    json input = {
        "resourceType": "Patient",
        "name": [
                "family": "Simpson"

    // Parse it - you can pass the input (as a string or a json) and the
    // type of the resource you want to parse.
    international401:Patient patient = check fhirParser:parse(input).ensureType();

    // Access the parsed data
    fhir:HumanName[]? names =;
    if names is () || names.length() == 0 {
        return error("Failed to parse the names");
    io:println("Family Name: ", names[0]);

HL7? Ballerina is HL7

Ballerina offers built-in support for the HL7 messaging standard, which is still the most commonly used standard in the healthcare industry to facilitate the exchange of information between different systems. With Ballerina, parsing HL7 messages is a breeze, simplifying the processing and exchange of healthcare data.

// The following example is a simple serialized HL v2.3 ADT A01 message.
"198808181126|SECURITY|ADT^A01^ADT_A01|MSG00001|P|2.3||\rEVN|A01|200708181123||" +
"\rPID|1||PATID1234^5^M11^ADT1^MR^GOOD HEALTH HOSPITAL~123456789^^^USSSA^SS||" +
"BATMAN^ADAM^A^III||19610615|M||C|2222 HOME STREET^^GREENSBORO^NC^27401-1020|GL|" +
"(555) 555-2004|(555)555-2004||S||PATID12345001^2^M10^ADT1^AN^A|444333333|987654^NC|" +
"\rNK1|1|NUCLEAR^NELDA^W|SPO^SPOUSE||||NK^NEXT OF KIN$\rPV1|1|I|2000^2012^01||||" +

public function main() returns error? {
    // This message, ADT^A01 is an HL7 data type consisting of several components, so we
    // will cast it as such. The ADT_A01 class extends from Message, providing specialized
    // accessors for ADT^A01's segments.
    // Ballerina HL7 provides several versions of the ADT_A01 record type, each in a
    // different package (note the import statement above) corresponding to the HL7
    // version for the message.
    hl7v23:ADT_A01 adtMsg = check hl7:parse(msg).ensureType(hl7v23:ADT_A01);
    hl7v23:XPN[] patientName =;
    io:println("Family Name: ", patientName[0].xpn1);

Powerful health data mapping

Ballerina makes data mapping seamless through its pre-built HL7v2.x to FHIR transformation functionalities, making short work of healthcare data mapping tasks. Ballerina has cracked the challenge of mapping one kind of data value to another kind of data value, simultaneously as code and picture, so that both are simple, powerful, and boundless.

final string msg =
"HOSPITAL|198808181126|SECURITY|ADT^A01^ADT_A01|MSG00001|P|2.3||\rEVN|A01|" +
"200708181123||\rPID|1||PATID1234^5^M11^ADT1^MR^GOOD HEALTH HOSPITAL~123456789^^^USSSA^SS||" +
"BATMAN^ADAM^A^III||19610615|M||C|2222 HOME STREET^^GREENSBORO^NC^27401-1020|GL|" +
"(555)555-2004|(555)555-2004||S||PATID12345001^2^M10^ADT1^AN^A|444333333|987654^NC|" +
"\rNK1|1|NUCLEAR^NELDA^W|SPO^SPOUSE||||NK^NEXT OF KIN$\rPV1|1|I|2000^2012^01||||" +

public function main() returns error? {
    // Transform HL7v2 message to FHIR R4.
    // You can pass a HL7v2 message and get a FHIR R4 Bundle based on
    // the mappings defined at
    json v2tofhirResult = check v2tofhirr4:v2ToFhir(msg);
    io:println("Transformed FHIR message: ", v2tofhirResult.toString());

    // v2tofhirr4 library exposes these low level functions as well,
    // In this case, by using stringToHl7 function you can pass a HL7v2 message string and get a parsed HL7v2 message model.
    hl7:Message hl7msg = check v2tofhirr4:stringToHl7(msg);
    if (hl7msg is hl7v23:ADT_A01) {
        // if you want to work with HL7v2 segments directly.
        // Transform HL7v2 PID to FHIR R4 Patient Name.
        r4:HumanName[] patientName = v2tofhirr4:pidToPatientName(,;
        io:println("HL7v23 PID Patient Name: ", patientName[0].toString());
Powerful health data mapping

Connect to EMRs, EHRs, data sources and more

Ballerina has 100s of connectors to well-known Health Systems such as Epic, Cerner, athenahealth, and non-health systems such as Salesforce, and can connect to any backend that has a FHIR, HL7, or Open API interface. Go below the hood and connect directly to a database as well if that is the only way to fetch data.

// Create a FHIR client configuration
fhirClient:FHIRConnectorConfig cernerConfig = {
    baseURL: base,
    mimeType: fhirClient:FHIR_JSON,
    authConfig: {
        tokenUrl: tokenUrl,
        clientId: clientId,
        clientSecret: clientSecret,
        scopes: scopes

// Create a FHIR client
final fhirClient:FHIRConnector fhirConnectorObj = check new (cernerConfig);

public function main() returns error? {
    // Get a patient resource by id
    fhirClient:FHIRResponse fhirResponse = check fhirConnectorObj->getById("Patient", "12724067");
    io:println("Cerner EMR response: ", fhirResponse.'resource);

    // Search for patients who has the given name "John" and birthdate greater than 2000-01-01
    fhirClient:FHIRResponse searchResponse = check fhirConnectorObj->search("Patient", {
        "given": "John",
        "birthdate": "gt2000-01-01"
    io:println("Cerner EMR search response: ", searchResponse.'resource);

Powerful EDI for claims

Ballerina has powerful support for Electronic Interchange Formats (EDI). In healthcare, this means out of the box handling of X12, 834s, 837s and more region specific standards via native schema mapping. Go from EDI formats to Ballerina Records and back; Do Data Mapping on that and you’re off to the races!

public function main() returns error? {
    string enrollmentRequest = check io:fileReadString("enrollments/E0_1.edi");
    m834:EDI_834_Benefit_Enrollment_and_Maintenance enrollment =
         check hmart:read(enrollmentRequest, hmart:EDI_834).ensureType();
Powerful EDI for claims

AI pair programming for your code

AI code gen like Github Copilot knows Ballerina. Ballerina knows healthcare. Why do all the work? Let AI do at least half of it for you!

AI pair programming for your code

(Extra!) APIs are the new DLLs on Choreo

Deploy healthcare accelerator code into WSO2 Choreo as APIs and access accelerator functionality not only from Ballerina but also other languages such as Java, .Net and Python as internal APIs, or from other systems as external APIs. Bring your own code to the party on Choreo.

(Extra!) APIs are the new DLLs on Choreo