.NET SDK 6: Unifying the model and preparing for the future of FHIR
Subscribe to our newsletter
SubscribeThe Firely .NET SDK has grown alongside FHIR for more than a decade. As the standard expands and real-world implementations become more complex, the SDK needs to evolve with it. SDK 6 is the next step in that evolution, introducing the most significant architectural updates we’ve ever made.
This release introduces a unified model for working with FHIR data, adds far more flexibility for handling dealing with unknown or incorrect data, and lays the foundation for upcoming versions of FHIR, including R6.
SDK 6 brings together everything we’ve learned over the years, and it finally unifies two worlds that have lived side by side for far too long: POCOs and ITypedElement.
In this post, I’ll walk through why we made these changes and how they will make your work with FHIR simpler, safer, and more future-proof.
Why SDK 6? Solving the “two worlds” problem
For years, the SDK had two different ways of processing data:
- POCOs: statically generated .NET classes that are easy to use but limited when the data is incomplete, incorrect, or contains new elements.
- ITypedElement: a more flexible, dictionary-based structure with its own metadata and type system used for FhirPath and Validation.
Both had their strengths, but maintaining both created real challenges:
- Two type systems
- Two parsing and serialization paths
- Two navigation models
- Repeated object creation and re-parsing
And in real implementations, developers often had to convert resources back and forth to evaluate FhirPath, run validation, or troubleshoot issues. Sometimes the behavior even differed depending on which API you used. Those inconsistencies only showed up when your users found them, which is never a fun experience for anyone.
Most developers prefer the simplicity of POCOs. I do too.
But POCOs alone did not provide the flexibility to work with unknown or incorrect data. SDK 6 finally resolves this by unifying the entire model behind the scenes.
A unified model: POCOs, now with full metadata support
In SDK 6, POCOs remain the main way developers work with FHIR resources, but now they have the flexibility that used to exist only in ITypedElement.
We introduced a new internal representation called PocoNode. It bridges the gap between the familiarity of POCOs and the dynamic nature of ITypedElement needed for validation, navigation, and FhirPath evaluation.
This unification means:
- Validation works directly on POCOs
- FhirPath evaluation works directly on POCOs
- Error reporting is clearer and more precise
- Navigation through resource trees behaves predictably
- Developers no longer switch mental models halfway through their code
- The SDK no longer maintains two separate architectures
One representation. One behavior. One set of expectations.
In other words: POCO is still king, but now POCO can do everything the dynamic model could do.
Overflow: Flexible, safer handling of real-world data
Anyone who has worked with FHIR in the real world knows that data does not always follow the rules. You encounter:
- Unknown or misspelled elements
- Wrong or unexpected datatypes
- Lists where a single value was expected
- Fields from older or newer FHIR versions
- Experimental or custom extensions
Earlier versions of the SDK often had to drop this content or fail the parse. That caused lost information, confusing errors, or extra cleanup layers that nobody really wanted to build.
SDK 6 introduces overflow, a structured place to store anything that does not fit into the POCO model. Instead of discarding unknown or unexpected content, the SDK preserves it.
This gives you:
- More forgiving parsing
- Reliable round-tripping across versions
- Clearer debugging
- Safer ingestion of mixed-version data
- Less data loss overall
If your systems interact with multiple FHIR versions or legacy implementations, overflow will make a noticeable difference.
A smarter, more predictable parsing pipeline
With the data model unified, the parsing infrastructure could finally evolve too. SDK 6 introduces parsers that work with overflow and have a more flexible approach to what is considered “valid data”.
By using these new capabilities, the parser now comes with several built-in modes that you can extend:
- STRICT, report everything we can
- DEFAULT, safe and validation-aware
- RECOVERABLE, accept anything as long as no data-loss occurs
- BACKWARDSCOMPATIBLE, ideal for mixed versions
- OSTRICH, ignore almost everything and just parse it anyway
These parsing personalities help developers choose how strict or permissive their workflows should be, without needing extra glue code. And because everything runs through one shared model, the behavior of the SDK is far more predictable.
Preparing for FHIR R6 and beyond
FHIR continues to evolve quickly. SDK 6 is designed to evolve with it. FHIR R6 introduces non-core resources that do not have static POCO generators. Older SDK versions could not handle these. SDK 6 can.
The flexibility over overflow, combined with the metadata-first architecture allows the SDK to process:
- Experimental resources
- Custom resources
- R6 modules without generated classes
- StructureDefinitions that describe concepts not yet modeled in code
This flexibility helps developers adopt new FHIR features faster and with fewer workarounds.
Modern .NET improvements and cleanup
Beyond the architectural changes, SDK 6 includes a number of modernization updates:
- Full support for .NET 8 and .NET Standard 2.1 (and removes outdated platforms)
- Nullable annotations across POCOs for better compiler warnings
- Async-only FHIRClient for clearer usage
- Cleanup of obsolete methods
- Common datatypes (Address, Duration, HumanName, Ratio) now moved into Base
- More consistent equality and comparison logic
This makes the SDK safer, cleaner, and more in line with modern .NET development practices.
What this means for developers
With SDK 6, you can expect:
- A simpler codebase: No more juggling POCOs and ITypedElement models.
- Better resilience in real-world scenarios: Messy, cross-version, or partially invalid data no longer causes hard failures or data loss.
- A more powerful validation experience: POCO-based validation is now richer and more accurate.
- Future readiness: Support for R6 and custom or experimental resources is built in.
- Cleaner, modern APIs: A clearer, more predictable developer experience.
SDK 6 is a major step forward. Not just for Firely’s SDK, but for anyone building on top of the FHIR standard.
Final thoughts
Working on this SDK for more than ten years has taught me a lot about what works and what does not. Our .NET SDK 6 release has been an opportunity to bring those lessons together, simplify long-standing complexity, and prepare the codebase for what comes next.
My hope is that this release makes your day-to-day work easier, especially when dealing with real-world data and evolving FHIR specifications.
As always, your feedback is welcome. This SDK grows with the community.