FHIR Profiles, Extensions, and Implementation Guides: how FHIR gets localized
Every country adopting FHIR must localize the standard through three tightly coupled concepts: Profile (additional constraints layered on top of a base Resource), Extension (new fields not present in FHIR base), and Implementation Guide (the published package containing the full standard). VN Core IG is how Vietnam applies these constraints for social health insurance (BHYT), VNeID, the Vietnamese ICD-10, the new 34-province directory introduced by Resolution 202/2025/QH15, and the electronic medical record (EMR) model defined by Circular 13/2025/TT-BYT.
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
.tgzpackage. - 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.5.0 with canonical
http://fhir.hl7.org.vn/core, hosting 52 Profiles and 44 Extensions in the source repository.
On this page
- Why FHIR base is not enough for Vietnamese healthcare
- What a Profile is — the constraint pattern
- Four common types of constraints
- Extensions — when and how to write them
- FSH and SUSHI — the standard toolchain
- Implementation Guide — structure and build process
- Case study: VN Core IG
- International comparison: US, JP, KR, CH, AU Core
- Frequently asked questions
- References and further reading
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 ward or commune, the third-level administrative unit that became critical in Vietnam after Resolution 202/2025/QH15.
Vietnamese healthcare practice imposes a long list of specific requirements that FHIR base does not address directly. The EMR rules in Circular 13/2025/TT-BYT (Ministry of Health) require attaching the personal identification number (the 12-digit national ID card, or CCCD). BHYT claims processing requires the BHYT card number, the participant category code, the initial registered facility, and the validity period. Hospital records following the Decision 4210/QĐ-BYT data standard need ethnicity from the official catalog of 54 ethnic groups, an occupation from the General Statistics Office (TCTK) directory, the hospital's classification rank, and the technical care tier under the new two-tier model.
Profiles and Extensions solve this localization problem by adding constraints and data elements while preserving read/write interoperability with any conformant FHIR R4 server. A Patient instance that conforms to VNCorePatient is still a valid Patient under HL7's core specification — a property that is essential for keeping FHIR globally interoperable.
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 slice CCCD 1..1 MS, BHYT 0..* MS, MRN 0..* MS
- extension contains ethnicity, occupation, ward, province
- address conforms to VNCoreAddress
- address.country fixed = "VN" 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:
- Never loosen cardinality: if base defines
1..1, a Profile cannot relax it to0..1; if base says1..*, you cannot move to0..*. - Never change the data type: an element declared as
stringin base cannot be re-typed asintegerin the Profile; you may only restrict to types already permitted in a base choice type. - You may tighten cardinality:
0..1can become1..1;0..*can become1..*or1..3. - You may strengthen binding: from
exampletopreferred,extensible, orrequired— but you cannot weaken a binding that is alreadyrequiredin 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 the same thing as cardinality. A 0..1 MS element may still be absent from an instance — but the system has to be able to handle it when present. A 1..1 MS element must have a value; if the business case has none, the system must use data-absent-reason, as VNCorePatient prescribes for the CCCD slice in special cases such as newborns before 2016 or foreign nationals.
Slicing
Slicing partitions an array into "slices" identified by a discriminator. VNCorePatient slices identifier by system to separate the CCCD, BHYT card, medical record number (MRN), passport number, and birth certificate number:
* identifier ^slicing.discriminator.type = #value
* identifier ^slicing.discriminator.path = "system"
* identifier ^slicing.rules = #open
* identifier contains
CCCD 1..1 MS and
BHYT 0..* MS and
MRN 0..* MS and
passport 0..1 MS and
GKS 0..1 MS
* 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 = #value and path = "system" tells the validator to distinguish slices based on the value of identifier.system. The #open rule allows additional slices beyond those listed (for example a hospital's internal MRN); a #closed rule would block any slice that has not been declared.
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 has 44 extensions in its source repository, including VNCoreExtEthnicity (ethnicity), VNCoreExtWard (ward/commune), VNCoreExtProvince (province), VNCoreExtFacilityCareLevel (technical care tier), VNCoreExtOrgRank (facility class), VNCoreExtTreatmentOutcome (treatment outcome), and 38 others 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-nationality), 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: "Profile Patient cho Việt Nam, gắn với số định danh cá nhân
theo TT 13/2025/TT-BYT và NĐ 102/2025/NĐ-CP."
* identifier 1..* MS
* identifier ^slicing.discriminator.type = #value
* identifier ^slicing.discriminator.path = "system"
* identifier ^slicing.rules = #open
* identifier contains
CCCD 1..1 MS and
BHYT 0..* MS and
MRN 0..* MS
* identifier[CCCD].system = "http://fhir.hl7.org.vn/core/sid/cccd" (exactly)
* identifier[CCCD].value 1..1 MS
* identifier[CCCD].value obeys vn-cccd-format
* name 1..* MS
* gender 1..1 MS
* birthDate 1..1 MS
* address only VNCoreAddress
* extension contains
VNCoreExtEthnicity named ethnicity 0..1 MS and
VNCoreExtOccupation named occupation 0..1 MS
* 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.
A few IGs (most notably CH Core and early US Core releases) still maintain hand-written StructureDefinition JSON. The trend since 2022, however, is to migrate everything to FSH for its maintenance benefits: readable diffs, effective code review, and dependency resolution handled automatically by SUSHI.
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 the Vietnamese national Implementation Guide developed by Omi HealthTech (OmiGroup) and contributed to the country's digital health community. The current version (per the sushi-config.yaml in the repository) is 0.5.0, with the following technical parameters:
| Property | Value |
|---|---|
| IG ID | hl7.fhir.vn.core |
| Canonical URL | http://fhir.hl7.org.vn/core |
| FHIR Version | R4 (4.0.1) |
| Version | 0.5.0 |
| Status | draft |
| Jurisdiction | VN |
| License | CC-BY-4.0 |
| Profiles / Extensions count | 52 Profiles, 44 Extensions in the source repository |
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 was not built in a vacuum. The table below compares the size and adoption level of the National Core IGs that Omi HealthTech consulted during design:
| IG | Country | Profile count | Status | Adoption level |
|---|---|---|---|---|
| US Core | United States | ~30 | STU 8 (trial use) | Required for EHR certification (ONC/ASTP) |
| JP Core | Japan | ~50 | v1.x | Recommended by MHLW; bridges to SS-MIX2 |
| KR Core | South Korea | ~20 | draft | KOSMOS pilot and major EMR vendors |
| CH Core | Switzerland | ~15 | v3+ | Required for the EPD (electronic patient dossier) |
| AU Core | Australia | ~20 | v1.x | ADHA recommendation; My Health Record |
| VN Core | Vietnam | 52 | draft 0.5.0 | Community draft, preparing for HL7 Affiliate |
VN Core is comparable in size to JP Core in profile count and larger than US Core or CH Core. The key difference is that VN Core, even at version 0.5.0, already covers the BHYT claims block (Claim, Coverage, ExplanationOfBenefit, PaymentReconciliation) — territory that US Core does not address (ONC delegates this to Da Vinci) and JP Core only touches superficially. The reason: Vietnam's single-payer BHYT architecture turns the XML 4210 → FHIR Claim mapping into a make-or-break use case for every HIS vendor.
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 a convenience DSL, not a required specification. You can still author StructureDefinitions directly in JSON or XML and drop them into input/resources/ for the IG Publisher to pick up. That said, every National Core IG released since 2022 (including VN Core, AU Core, and KR Core) uses FSH because the maintainability benefits are decisive.
Are Implementation Guides versioned?
Yes — under SemVer. VN Core is at 0.5.0; minor versions bump when Profiles/Extensions are added without breaking compatibility, patch versions for narrative fixes or minor binding tweaks, and major versions for breaking cardinality changes. Any IG referencing another (a dependency) must pin a specific version through the dependencies block in sushi-config.yaml.
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?
Always prefer extensions already standardized by HL7 or by stable published international IGs (US Core, IPS, IPA). Only create a new extension when (1) the concept is Vietnam-specific or (2) the standard extension does not bind the ValueSet you need. VN Core reuses HL7's patient-birthPlace, patient-nationality, and patient-religion rather than authoring local equivalents.
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
- FHIR R4 — Profiling FHIR (§5.2)
- FHIR R4 — Conformance Rules: Must Support
- FHIR R4 — Address datatype definition
- FHIR R4 — JSON representation
- FSH School — FHIR Shorthand documentation
- US Core IG — STU 8
- JP Core IG
- CH Core IG
- AU Core IG
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).