Value sets & ConceptMaps
Code systems don't make systems interoperable — value sets and maps do. The difference between 'which codes are allowed here' and 'what does this code mean over there'.
In one line
A code system is a dictionary. A value set says which words are permitted in this particular blank. A ConceptMap says what this word becomes in another language. Almost every real interoperability failure is a value-set or mapping failure, not a code-system one.
The three-layer idea
Get this hierarchy straight and most terminology confusion dissolves:
- CodeSystem — the universe of concepts. SNOMED CT has hundreds of thousands. LOINC has tens of thousands.
- ValueSet — the subset allowed in one place. "The codes permitted in
AllergyIntolerance.codefor this profile." - ConceptMap — the translation between two of those worlds.
Here's the part that surprises people: SNOMED CT is too big to be useful on its own. A form field bound to "any SNOMED concept" is a field bound to nothing. The user can pick a procedure where a diagnosis belongs. Freedom at the point of data entry is not a gift; it's how a database fills with unusable data.
The value set is where usefulness comes from. It's the act of saying no.
Value sets: binding strength is the real decision
In FHIR, a value set is attached to an element with a binding strength, and this is where implementers make or break their data quality:
- required — you must use a code from this set. No exceptions.
- extensible — use one from the set if it fits; if genuinely nothing does, you may go outside.
- preferred — encouraged, not enforced.
- example — pure illustration. Binds nothing.
The trap is extensible. It reads like a sensible compromise and behaves like a trapdoor:
every implementer decides for themselves that nothing quite fits, and within a year the field
contains six local vocabularies. Extensible bindings are where interoperability quietly
dies. If a field matters, bind it required and mean it.
Value sets can be enumerated (an explicit list) or defined by rules — for example, via ECL: "all descendants of Diabetes mellitus." Rule-based sets stay correct as the code system evolves; enumerated ones start rotting the day you publish them.
ConceptMaps: translation, and the honesty problem
A ConceptMap relates concepts across systems — local codes → LOINC, SNOMED → ICD-10 for classification, one hospital's vocabulary → a national profile.
The essential part is the equivalence on each mapping, because mappings are rarely clean:
- equivalent / equal — genuinely the same concept.
- wider — the target means more than the source.
- narrower — the target means less.
- inexact — related, not the same.
- unmatched — nothing over there means this.
That vocabulary exists because most real-world mappings lose information, and pretending
otherwise is how bad data gets laundered into confident dashboards. A narrower mapping means
you asserted something the source never said. An unmatched is not a failure of the map — it's
the map telling you the truth.
The discipline: record the equivalence honestly, and let downstream decide what it can
tolerate. A map that claims everything is equivalent isn't a better map, it's a dishonest
one.
Where you'll meet them
- Profiles — US Core and NRCeS are, in large part, a stack of value-set bindings. That's mostly what "profiling" is: constraining freedom.
- Terminology servers — Snowstorm and
friends expand value sets and run
$translateagainst ConceptMaps, so your app doesn't hard-code any of it. - Migration — every "legacy system → FHIR" project is, underneath the plumbing, a mapping exercise. The plumbing is a week. The mapping is the project.
The one-sentence version
Interoperability is not what the standard gives you — it's what the value set takes away, plus an honest account, in the ConceptMap, of what you lost in translation.
References
Related entries
SNOMED CT®, LOINC®, ICD and other terminologies are the property of their respective owners and are shown for education under their licences. Licences & attributions