Why Terminologies Matter
The semantic interoperability problem
Two hospitals exchange a Condition resource for a patient with diabetes. Hospital A codes it as 44054006 from SNOMED CT. Hospital B codes it as E11 from ICD-10. A third system uses a local code DM2 with no system specified.
All three mean the same clinical thing, but a system receiving these resources cannot automatically know that without additional knowledge. This is the semantic interoperability problem — getting data across systems is the easy part; ensuring both sides mean the same thing is hard.
FHIR solves this through a structured terminology framework: CodeSystems define what codes mean, ValueSets select which codes are valid in a context, and bindings connect ValueSets to specific resource elements.
CodeSystem — the source of codes
A CodeSystem defines a set of codes and their meanings. Every code used in FHIR must belong to a CodeSystem, identified by a URI. The URI is the system, the code is the value — together they are unambiguous.
Major CodeSystems in FHIR
| CodeSystem | Used for | Example |
|---|---|---|
| SNOMED CT | Diagnoses, findings, procedures, anatomy | 44054006 — Diabetes type 2 |
| LOINC | Lab tests, observations, panels, vitals | 2339-0 — Blood glucose |
| ICD-10 | Diagnoses for billing and epidemiology | E11 — Type 2 diabetes |
| ATC | Medications by anatomical/therapeutic class | A10BA02 — Metformin |
| UCUM | Units of measure | mg/dL, mmol/L, kg |
Notice that Condition uses both SNOMED CT and ICD-10 in the same code.coding[] array. FHIR allows — and encourages — multiple codings for the same concept from different systems. The systems using the data can consume the coding they understand.
ValueSet — selecting codes for a context
A ValueSetdoes not define codes — it selects a subset of codes from one or more CodeSystems for use in a specific context. The distinction matters: SNOMED CT has ~350,000 concepts. A ValueSet for "condition clinical status" selects exactly 6 of them.
Condition.clinicalStatus binding (required)
"clinicalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active",
"display": "Active"
}]
}
// Must use one of: active | recurrence | relapse | inactive | remission | resolved
// Defined in ValueSet: http://terminology.hl7.org/ValueSet/condition-clinical
// Binding strength: required — any other code is a validation errorBinding — connecting ValueSets to elements
A binding in a profile (or in the base spec) connects a ValueSet to a specific element. The binding strength defines how strictly the ValueSet must be followed:
| Strength | Rule | Example |
|---|---|---|
| required | Must use a code from this ValueSet. Validation fails if not. | Patient.gender, Condition.clinicalStatus |
| extensible | Prefer codes from this ValueSet. May use other codes if needed and documented. | Observation.code (vital signs) |
| preferred | Use codes from this ValueSet if possible. Not enforced by validators. | Condition.code (SNOMED CT preferred) |
| example | Illustrative only. No constraint enforced. | Observation.bodySite |
SNOMED CT vs LOINC — what each is for
The most common confusion in clinical terminology is when to use SNOMED CT and when to use LOINC. They are not interchangeable.
SNOMED CT
What: clinical concepts — conditions, procedures, anatomy, organisms, substances.
Use in FHIR: Condition.code, Procedure.code, AllergyIntolerance.code, body sites, clinical findings.
Example: 44054006 — Diabetes mellitus type 2
LOINC
What: observable entities — laboratory tests, vital sign measurements, clinical assessments, document types.
Use in FHIR: Observation.code, Observation.component.code, DiagnosticReport.code.
Example: 2339-0 — Glucose [Mass/volume] in Blood
Practical rule
Use LOINC to identify what was measured or observed. Use SNOMED CT to identify what the finding or condition is. A blood glucose test is LOINC 2339-0. The resulting diagnosis (diabetes) is SNOMED CT 44054006.
When to create a custom CodeSystem
Sometimes no standard CodeSystem covers the concept you need — a country-specific identifier type, an institutional ward code, a local classification. In that case you define a custom CodeSystem under your domain URL and publish it as a FHIR resource.
In FHIR.sk, the FhirSkIdentifierType CodeSystem (https://fhir.sk/fhir/CodeSystem/identifier-type) defines three custom identifier types: nationalId, hospitalNumber, insuranceId. This is a synthetic example — the pattern is the same in real IGs.
Try it in the Terminology Explorer
Browse the bundled ValueSets and CodeSystems referenced in this article, including the LOINC vital signs ValueSet and custom FHIR.sk CodeSystem.
Open Terminology Explorer →