FHIR Profiles, Extensions, and Implementation Guides: how FHIR gets localized

Many national programs and organizations localize FHIR through Profiles, Extensions, Terminology, and Implementation Guides. VN Core is this project's trial-use proposal for Vietnamese use cases such as BHYT, identity, the Vietnamese ICD-10, and administrative addresses; it is neither the only possible approach nor an officially recognized national standard.

This page is for developers, HIS/EMR vendors, and regulators who need to understand how Profiles, Extensions, and Implementation Guides work before reading a specification or evaluating a product's compliance with the Vietnamese FHIR profile.

TL;DR

  • A Profile is a StructureDefinition that adds constraints (cardinality, binding, Must Support, slicing, fixed value) on top of a base Resource without breaking compatibility.
  • An Extension introduces a data element that FHIR base does not provide; each extension has its own canonical URL and must be declared in the IG.
  • An Implementation Guide is the release package — Profiles, Extensions, Terminology, Examples, and narrative content compiled into an HTML site and a .tgz package.
  • FSH (FHIR Shorthand) is a DSL compiled by SUSHI to generate StructureDefinition JSON, replacing hand-written XML/JSON.
  • VN Core IG is currently at version 0.8.0 with canonical http://fhir.hl7.org.vn/core, publishing 86 Profiles and 56 Extensions.

1. Why FHIR base is not enough for Vietnamese healthcare

The base Resources of FHIR R4 (4.0.1, 146 resources) are designed at a globally generic level. The standard Patient resource allows identifier[] with cardinality 0..* and does not require any specific identifier system. It defines address with the components line, city, district, state, postalCode, and country — but no coded field for a ward or commune, the local administrative unit in Vietnam's two-tier local-government model after Resolution 202/2025/QH15.

Vietnamese healthcare practice imposes requirements that FHIR base does not address directly. Circular 13/2025/TT-BYT sets an EMR rollout for hospitals and other healthcare facilities providing inpatient, day, or outpatient treatment; Article 1(3) requires EMR information to be linked to the personal identification number of Vietnamese citizens and of foreign nationals who have been issued an electronic identification account. The Circular neither creates two alternative identifiers nor itself mandates a 12-digit CCCD slice in FHIR: the 12-digit format comes from identity law, while the CCCD slice cardinality is a trial-use VN Core conformance decision. BHYT processing uses fields such as the BHYT number, beneficiary group, initially registered facility, and applicable validity period. Healthcare, KCB, and BHYT datasets also use ethnicity, occupation, facility classification, professional-care tier, and administrative-unit codes under their respective source instruments.

Profiles and Extensions address localization by adding constraints and data elements on the FHIR R4 structure. An instance conforming to VNCorePatient must remain valid against base Patient, but that inheritance does not guarantee that every R4 server or client understands, validates, or preserves VN Core extensions and semantics. An interoperability claim therefore requires both parties to use the exact IG package and version, declare capabilities in a CapabilityStatement, and test validation, round-trip behavior, and the agreed workflow contract.

2. What a Profile is — the constraint pattern

A Profile is a StructureDefinition that derives (inherits) from either a base Resource or another Profile and adds further constraints. A Profile does not define a new data structure; it merely narrows the set of valid values that an instance must satisfy. The inheritance diagram for VNCorePatient illustrates this clearly:

Patient (base — http://hl7.org/fhir/StructureDefinition/Patient)
   └── derive
       VNCorePatient (http://fhir.hl7.org.vn/core/StructureDefinition/vn-core-patient)
       - identifier slices: CCCD 1..1 MS; BHYT/BHXH/GKS/HC 0..1 MS; MRN 0..* MS
       - Patient extensions: ethnicity, occupation, citizenship, religion, birthPlace
       - address 0..* MS, constrained to VNCoreAddress
       - VNCoreAddress: province and ward extensions 0..1 MS;
         a Vietnamese address is expected to carry a coded province

The four immutable rules of profiling

When authoring a Profile there are four compatibility rules that absolutely must be respected. Violating any one of them turns the Profile into something that is no longer a valid constraint on the base, which means instances cannot be read by a standard FHIR client:

  1. Never loosen cardinality: if base defines 1..1, a Profile cannot relax it to 0..1; if base says 1..*, you cannot move to 0..*.
  2. Never change the data type: an element declared as string in base cannot be re-typed as integer in the Profile; you may only restrict to types already permitted in a base choice type.
  3. You may tighten cardinality: 0..1 can become 1..1; 0..* can become 1..* or 1..3.
  4. You may strengthen binding: from example to preferred, extensible, or required — but you cannot weaken a binding that is already required in base.

These four rules enforce the Liskov substitution principle: every instance valid against a Profile is also valid against the base, but not necessarily vice versa. This is exactly why a FHIR validator can simultaneously check a Patient instance against base and against VNCorePatient without any contradiction arising.

3. Four common types of constraints

Cardinality

Cardinality defines how many times an element may appear. FHIR notation uses a min..max pair: 0..1 is a single optional value, 1..1 is a single required value, 0..* is an optional repeating element, and 1..* is a required repeating element with at least one occurrence. VNCorePatient tightens identifier 1..* to require every patient to carry at least one identifier, then uses slicing to fix the CCCD slice at 1..1.

Binding strength

Binding ties a code, Coding, or CodeableConcept element to a ValueSet. FHIR R4 defines four levels:

  • required — the instance must use a code from the ValueSet; the validator throws an error otherwise.
  • extensible — prefer the ValueSet; codes outside it are only acceptable when no suitable code exists inside.
  • preferred — recommended but not enforced.
  • example — illustrative only; no binding constraint.

The VNCoreCondition profile binds Condition.code to the Vietnamese ICD-10 ValueSet at the extensible level. This allows SNOMED CT to be used when an ICD-10 code is not granular enough, while keeping the Vietnamese ICD-10 as the preferred catalog.

Must Support

Must Support (marked MS) requires any system claiming Profile conformance to support the element in the way the IG specifies. The FHIR specification deliberately leaves "support" undefined at the global level — each IG must spell it out. VN Core defines MS to mean: a storing server must round-trip read/write the element; a sending client must populate it when data is available; UI surfaces must render the element when required.

Must Support is not cardinality. A 0..1 MS element may be absent while conforming systems still have to process it when present. Cardinality 1..1 requires the element to be present; a primitive may carry a data-absent-reason extension without a primitive value when the profile permits it. VNCorePatient uses this pattern for the CCCD slice in special cases and requires an alternative identifier or appropriate reason.

Slicing

Slicing partitions an array into slices identified by a discriminator. Since VN Core v0.9.0, VNCorePatient classifies identifier using a pattern on Identifier.type, rather than using Identifier.system as the discriminator. This keeps national system URIs fixed for CCCD, BHYT, and BHXH while allowing each facility to publish its own MRN namespace:

* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "type"
* identifier ^slicing.rules = #open
* identifier contains
    CCCD 1..1 MS and
    BHYT 0..1 MS and
    BHXH 0..1 MS and
    MRN 0..* MS and
    HC 0..1 MS and
    GKS 0..1 MS
* identifier[CCCD].type = $vn-identifier-type-cs#CCCD
* identifier[BHYT].type = $vn-identifier-type-cs#BHYT
* identifier[BHXH].type = $vn-identifier-type-cs#BHXH
* identifier[MRN].type = $vn-identifier-type-cs#MRN
* identifier[HC].type = $vn-identifier-type-cs#HC
* identifier[GKS].type = $vn-identifier-type-cs#GKS
* identifier[CCCD].system = "http://fhir.hl7.org.vn/core/sid/cccd" (exactly)
* identifier[BHYT].system = "http://fhir.hl7.org.vn/core/sid/bhyt" (exactly)

The combination of discriminator type = #pattern and path = "type" tells the validator to distinguish slices using the pattern on identifier.type. The #open rule still allows identifiers outside the declared slices. MRNs belong to the declared MRN slice, but identifier[MRN].system must be a namespace URI published by the assigning facility; uniqueness is defined by the system + value pair.

4. Extensions — when and how to write them

An Extension is the standard mechanism for adding a data element that FHIR base does not provide. Every Resource and DataType already has an extension field with cardinality 0..*; each extension is identified by a unique canonical URL. When Vietnamese practice needs to record the BHYT participant category on a card, VN Core defines VNCoreExtBHYTCardType:

Extension: VNCoreExtBHYTCardType
Id: vn-ext-bhyt-card-type
Title: "Loại đối tượng thẻ BHYT — BHYT Card Type"
Description: "Mã loại đối tượng tham gia BHYT theo QĐ 1351/QĐ-BHXH và QĐ 3276/QĐ-BYT"
Context: Coverage
* value[x] only CodeableConcept
* valueCodeableConcept from VNBHYTCardTypeVS (extensible)

The full canonical URL is http://fhir.hl7.org.vn/core/StructureDefinition/vn-ext-bhyt-card-type. When a Coverage instance references this extension, it serializes to JSON as:

{
  "resourceType": "Coverage",
  "id": "example-coverage-bhyt-01",
  "status": "active",
  "extension": [{
    "url": "http://fhir.hl7.org.vn/core/StructureDefinition/vn-ext-bhyt-card-type",
    "valueCodeableConcept": {
      "coding": [{
        "system": "http://fhir.hl7.org.vn/core/CodeSystem/vn-bhyt-card-type-cs",
        "code": "DN",
        "display": "Người lao động doanh nghiệp"
      }]
    }
  }]
}

Extensions come in two flavors. A simple extension carries a single value[x]. A complex extension nests multiple sub-extensions. VN Core currently publishes 56 extensions: 53 Vietnam-specific extensions and 3 reused official HL7 Patient extensions. The local set includes VNCoreExtEthnicity (ethnicity), VNCoreExtWard (ward/commune), VNCoreExtProvince (province), VNCoreExtFacilityCareLevel (technical care tier), VNCoreExtOrgRank (facility class), VNCoreExtTreatmentOutcome (treatment outcome), and other extensions serving Claim, Coverage, Device, and Encounter.

The design rule: only create an extension once you are sure that FHIR base and other published international IGs (US Core, IPS, IPA) do not already define one. If a concept already has a standard HL7 extension (for example patient-birthPlace, patient-citizenship), VN Core reuses it rather than minting a new one.

5. FSH and SUSHI — the standard toolchain

FSH (FHIR Shorthand) is the HL7-standardized DSL for writing Profiles, Extensions, ValueSets, and CodeSystems as concise text. SUSHI (SUSHI Unshortens SHorthand Inputs) is the official compiler that turns FSH into StructureDefinition JSON. The FSH + SUSHI combination replaces hand-written XML/JSON files that often run thousands of lines — the same profile can shrink from 800 lines of JSON to roughly 60 readable lines of FSH.

The following is the VNCorePatient profile written in FSH (abridged for illustration):

Profile: VNCorePatient
Parent: Patient
Id: vn-core-patient
Title: "Bệnh nhân VN Core — VN Core Patient Profile"
Description: "Vietnam Patient profile. The personal-identification/CCCD slice
is a trial-use VN Core conformance rule. Article 1(3) of Circular 13/2025/TT-BYT
requires EMR information to be linked to the personal identification number
of the specified groups; it does not make a VNeID account an alternative identifier."

* identifier 1..* MS
* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "type"
* identifier ^slicing.rules = #open
* identifier contains
    CCCD 1..1 MS and
    BHYT 0..1 MS and
    MRN 0..* MS

* identifier[CCCD].type = $vn-identifier-type-cs#CCCD
* identifier[CCCD].system = "http://fhir.hl7.org.vn/core/sid/cccd" (exactly)
* identifier[CCCD].value 1..1 MS
* identifier[CCCD] obeys vn-cccd-format
* identifier[BHYT].type = $vn-identifier-type-cs#BHYT
* identifier[MRN].type = $vn-identifier-type-cs#MRN

* name 1..* MS
* gender 1..1 MS
* birthDate 1..1 MS
* address only VNCoreAddress

* extension contains
    VNCoreExtEthnicity named ethnicity 0..1 and
    VNCoreExtOccupation named occupation 0..1

* obeys vn-patient-force-majeure-reason

Running sushi . in the project root reads every .fsh file, validates the syntax, resolves cross-references between Profiles, Extensions, and ValueSets, and emits fsh-generated/resources/StructureDefinition-vn-core-patient.json. The full IG build then continues with the IG Publisher (HL7's official publisher.jar) to produce the HTML site, the validation report, and the .tgz package.

An IG may be authored in FSH or directly as FHIR artifacts; the choice depends on project tooling and governance. FSH often improves readable diffs and review, while SUSHI validates FSH input and generates artifacts. Package dependencies, canonical versions, and semantic compatibility must still be declared, pinned, and tested; SUSHI does not automatically resolve every semantic dependency.

6. Implementation Guide — structure and build process

An Implementation Guide is the complete release package combining specification and documentation. A finished IG contains the following components:

  • Profiles — a StructureDefinition for each Resource that has been localized.
  • Extensions — StructureDefinitions for every additional field.
  • Terminology — CodeSystems (defining codes), ValueSets (the sets of codes usable in a binding), and ConceptMaps (mappings between code systems).
  • NamingSystem — registers the URIs for identifiers (CCCD, BHYT, BHXH, passport).
  • CapabilityStatement — describes the set of Resources and operations a server claiming IG conformance must support.
  • SearchParameter, OperationDefinition — custom search parameters and operations.
  • Examples — JSON instances that validate against the IG's own Profiles.
  • Pagecontent — narrative markdown that explains the business context, installation guidance, and example workflows.

The build is a two-step process. Step one: sushi . compiles FSH into StructureDefinition JSON and places the output in fsh-generated/. Step two: the IG Publisher (invoked through _genonce.sh) reads sushi-config.yaml, ig.ini, the FSH-generated artifacts, and the pagecontent, then produces the full HTML site under output/ together with the .tgz package destined for the FHIR Package Registry. Typical output includes index.html, qa.html (the QA report), artifacts.html (the artifact catalog), and the package.tgz file that other IGs can pull in via npm-style dependency resolution.

IGs follow SemVer versioning, declared in sushi-config.yaml. Whenever an IG depends on another, it must pin a specific version (for example [email protected]) to keep builds deterministic.

7. Case study: VN Core IG

VN Core is an Implementation Guide for the Vietnamese healthcare context, developed by Omi HealthTech and contributed to the country's digital health community. The current version (per the sushi-config.yaml in the repository) is 0.8.0, with the following technical parameters:

Property Value
IG IDhl7.fhir.vn.core
Canonical URLhttp://fhir.hl7.org.vn/core
FHIR VersionR4 (4.0.1)
Version0.8.0
Statusdraft
JurisdictionVN
LicenseCC-BY-4.0
Profiles / Extensions count86 Profiles, 56 published Extensions

The Profile set covers the resources central to hospital systems and BHYT operations: VNCorePatient, VNCorePractitioner, VNCorePractitionerRole, VNCoreOrganization, VNCoreOrganizationDepartment, VNCoreEncounter, VNCoreCondition, VNCoreObservation (with VitalSigns, BloodPressure, BodyHeight, BodyWeight, BodyTemperature, HeartRate, RespiratoryRate, SpO2, Lab, and TVM/YHCT specializations), VNCoreProcedure, VNCoreMedicationRequest, VNCoreMedicationDispense, VNCoreCoverage, VNCoreClaim, VNCoreClaimResponse, VNCoreExplanationOfBenefit, VNCorePaymentReconciliation, VNCoreImmunization, VNCoreAllergyIntolerance, VNCoreDevice, VNCoreImplantableDevice, VNCoreImagingStudy, VNCoreDiagnosticReport (with Lab, Imaging, and Pathology variants), VNCoreDocumentReference, VNCoreComposition, VNCoreConsent, VNCoreProvenance, VNCoreAuditEvent, and the VNCoreBHYTSubmissionBundle bundle that supports BHYT submission as required by Decree 164/2025/NĐ-CP.

The extensions focus on Vietnamese business fields that neither FHIR base nor the international IGs cover: ethnicity, occupation, technical care tier, healthcare facility class, BHYT participant category, BHYT settlement period, force-majeure reason for missing identifiers, consent method, audit-log retention, medical device registration code, medical device risk class (A/B/C/D under Decree 98/2021), and provincial/ward administrative units after Resolution 202/2025/QH15.

The VN Core terminology library bundles the local CodeSystems: the Vietnamese ICD-10 (per Decision 4469/QĐ-BYT), the catalog of 54 ethnic groups, the directory of 34 provinces, the BHYT participant codes from Decision 3276/QĐ-BYT, the traditional Vietnamese medicine (TVM/YHCT) terminology from Decisions 2552 and 3080/QĐ-BYT, and the SNOMED CT VN ConceptMaps from Decisions 2427/2493/2805/QĐ-BYT.

8. International comparison: US, JP, KR, CH, AU Core

VN Core references several national IGs. This table is a publication-status snapshot reviewed on 18 July 2026; Profile counts are not used to rank maturity or official recognition:

IG Country Reviewed release FHIR Governance note
US CoreUnited States9.0.0 STU9R4Published by HL7 International; regulatory applicability depends on the specific ASTP/USCDI program
JP CoreJapan1.1.2-clinsR4Its guidance states that this release is not approved by HL7 Japan
KR CoreSouth Korea2.0.0 STU2R4Release history published by HL7 Korea
CH CoreSwitzerland6.0.0 STU6R46.0.0 is stable; 7.0.0 is ballot in this snapshot
AU CoreAustralia2.0.0 Working StandardR4Status from the HL7 Australia release history
VN CoreVietnam0.8.0 trial-useR4Omi HealthTech initiative; not an official national standard

These IGs have different scopes and authorities, so Profile counts do not establish maturity. VN Core prioritizes BHYT, KSK SDC, and an IPS projection because those are in this project's scope. Mapping BHYT output data to FHIR remains adapter work that needs validation; it is not evidence that another national IG is deficient or that every HIS vendor has the same obligation.

Further reading: the page FHIR around the world and lessons for Vietnam takes a deeper look at architecture, governance, and adoption roadmaps for National Core IGs.

9. Frequently asked questions

Is FSH mandatory for writing Profiles?

No. FSH is an authoring DSL, not a required FHIR format. StructureDefinitions can be authored in JSON/XML or generated by other tools. Many modern IGs choose FSH for readable diffs and review, but this is not a rule for every National Core IG.

Are Implementation Guides versioned?

Yes. Each IG publishes its own versioning policy; VN Core uses SemVer for this project's release line. Package dependencies should declare specific versions in sushi-config.yaml so builds remain reproducible.

Can a Profile derive from another Profile?

Yes. A hospital can derive BachMaiPatient from VNCorePatient to add its own constraints (for example slicing identifier with a regex pattern for an internal MRN). The four immutable rules still apply: the child Profile must remain valid against every constraint of the parent.

When should you create a new Extension and when should you reuse a standard HL7 one?

Before creating an extension, check FHIR base, the extension registry, and the target IG. Reuse only when semantics, context, version, and dependency fit; do not import an extension from another IG merely because its name looks similar. VN Core reuses patient-birthPlace, patient-citizenship, and patient-religion after that comparison.

Does Must Support mean the data is required?

No. Must Support is a requirement on the system — it must be capable of handling the element. Cardinality is what determines whether an instance must contain data. A 0..1 MS element is valid even when absent.

10. References and further reading

HL7 standards documents

Vietnamese legal references

  • Circular 13/2025/TT-BYT (Ministry of Health) — Electronic medical records (issued 06/06/2025, effective 21/07/2025).
  • Decree 102/2025/NĐ-CP — Digital health data management (13/05/2025, effective 01/07/2025).
  • Law 91/2025/QH15 — Personal Data Protection (26/06/2025, effective 01/01/2026).
  • Resolution 202/2025/QH15 — Re-arrangement of provincial-level administrative units (12/06/2025).
  • Decision 4469/QĐ-BYT — Vietnamese ICD-10 (28/10/2020).
  • Decision 3276/QĐ-BYT — Catalog of patient-category codes for healthcare visits (17/10/2025).

Continue in the knowledge hub