This page is a 'quick start' to using the HL7 FHIR Registry. It is a work in progress and not yet complete (or necessarily correct). Feel free to comment though.


The FHIR registry has been established as a place where FHIR designers can save the conformance artefacts that are part of the profiling process in FHIR for discovery and downloading by others. These are FHIR resources such as StructureDefinitions (Profiles & Extension Definitions), ValueSets, CodeSystems, ImplementationGuide and others.

It is important to appreciate that this is a registry of packages - not just the FHIR artefacts. A package is a collection of resources that is based on the NPM package standard adapted to FHIR use - mostly by removing features not needed by FHIR.

The reason why we need packages and not just a single big FHIR server is that the FHIR world is not so simple as we once imagined it would be. Just the canonical will not give you a unique resource. There will be loads of versions over time, from different FHIR versions, etc.  so one big FHIR endpoint where you can search by canonical won't do the trick. It needs to be a combination of finding the right scope (version of a package + plus all the package versions that it depends on) and within that finding the right resource by canonical url (or likely ID for FHIR instances).

One use of Packages is to bundle together all the FHIR artefacts in an Implementation Guide to make them easier to locate and download. More specifically, a package will contain the FHIR resources for a specific version of an Implementation Guide - indeed, it was the complexity of versioning Implementation Guides and FHIR resources that led to the adoption of packages. It will not, however, contain the other components of an Implementation Guide such as the documentation or the IG layout (menus, images, summary pages etc). So a package is stable, versioned collection of resources - often those from an Implementation  Guide.

You can see the registry of Implementation Guides at

The registry exposes both a User Interface (UI) for use by humans and an API for computers. Note that if you click on one of the endpoints, you'll get a web page - as the request is coming from a browser the registry is trying to be helpful (or not). To find the actual API endpoint,  you need to click one of the options in the navigation tree on the left to get the API details - such as for the search or for downloading a package. Theres also swagger documentation available.

There are links at the bottom of the page with more details on the issues with the 'simple FHIR API' approach if you are interested.

There is also a video of a Birds of a Feather presentation at the November WGM by Ward Weistra

Package details

This section briefly describes a number of the key concepts you need to know about packages. There are links at the bottom of the page to more information, and on the registry itself. For more details, refer to the FHIR package specification

Name / id

All packages have a unique name - sometimes called a canonical name or id. This consist of 2 or more namespaces joined by dots - eg hl7.fhir.core and is assigned by the package creator.


All packages have a version - which uses semantic versioning in the format major.minor.patch 

Canonical url

If the package represents an IG, this is the canonical url of the IG, where the IG is located (ie it will resolve). It will generally match the package name (although the format is different) - and this is enforced for HL7 IGs. For example if the canonical url is, then the name / id will be 

Package structure

The package itself is a 'tarball' - a kind of compressed file. Within it is a specific folder structure and some defined files (like the package.json file, which is the package manifest).  The rest of the files - all the FHIR resources defined by the IG - are also included.

Downloading a package

>> talk about downloading a package - and the (local) global cache on a machine 

>> and tooling - Firely Terminal (ex torinox) & npm

Cost of Registry use

There is no charge for using the registry and downloading packages. Packages can also be freely uploaded - though the process is a bit involved and there are easier options (such as that do require a subscription. Note that does offer a free option for a single package.

Querying the Registry through the UI 

Making a query

To query the registry, navigate the browser to and you will be presented with the registry home page.

The main feature is the search box, where queries can be entered. You enter the search text into the box, and click the icon to perform the search. 

The search is powered by elasticSearch which queries both the metadata of the package (url, name, description, release notes, key words and so forth) and the package contents - the FHIR artefacts.  As there is some degree of 'fuzzy logic used, this does mean that you will get responses that don't necessarily exactly match the search string you have entered - though the order of the results should place the most relevant at the top of the list. 

Here's the response to a search string of "us core":

Some notes about the responses:

  • The first response - the US Core package itself - was based on matches to contents within the package. The first 4 of the resources are displayed. Clicking on the top part of the response (the package name) displays a more detailed page of the package and its contents. This has the package summary, contents and dependencies - and links to previous versions of this package. There are also links to the home page of the IG and the view (depending on the package, there may be more information there.
  • The first response also has the first 4 of the contents where there were matches found. They are hyperlinks, so clicking on them will take you to more details of the resource and also to the package
  • The second response indicates that the match came from metadata within the package (rather than the contents) - as indicated by the phrase "Match found at the package level". It can be tricky to determine why the match was made, but you can examine each response in detail should you wish.
  • Both responses show the key metadata about the package:
    •  Name
    • Canonical url
    • Date of package
    • Package version
    • FHIR version

In the left pane are a number of options to repeat and refine the search. You can:

  • Specify a particular FHIR version that you want
  • Indicate that you only want the latest version for each package. If this is unchecked, then every version of matching packages will be included in the search results. This is useful if you are looking for a specific version of a package, though can significantly increase the number of matches. If you are using this, then it's best to use the canonical url for the package as the search string.
  • Indicate the specific resource types of interest. If these are specified, the a match will only occur if the search string is in profiles of the given types  - or the package metadata.
  • Indicate the jurisdiction tha the IG is designed for. Leaving both checkboxes blank will not apply any filter (ie you get the full set of results - which is the same as checking both of them) - or you can specify either US only, non-US only or both.

Digging deeper

From the search results, you can drill down into further details. 

When a match was made to a specific FHIR artefact listed in the search result, then you can go directly to that resource (inside the package). Otherwise, the top click area takes you to the package. From there, you can dig into the package details (in the app) or to the actual IG itself (called the homepage)

Download a package

When you display the package details page (by clicking over the package details - the upper area in the example above) - the registry will display the download links to the upper right as show in the screenshot below. 

Example Searches

You can put anything into the search, and the registry will do its best to return pertinent matches, but the more specific you can make the query, the better the response will be. The most specific responses will be when a canonical url is supplied - though that is often not known (except in the case of finding an extension definition)

Note that the contents of these queries may/will change as packages are added / updated.

PurposeSample query stringResult and Discussion
Find a specific IGipsThe top result is the International Patient Summary IG (which I was after) and a few others that also had a match somewhere in the package. If I enter the canonical url for IPS (hl7.fhir.uv.ips) then I only get a single match.
Find existing extensions for some purpose to see if I need to create one, or whether there is one I can re-suereligionI want to find all extensions for religion. This search returned packages that contained a number of extension definitions from R2 through R4. This is probably one of the more important use cases, as re-use of extensions improves interoperability. 
Get the definition of an extension that is in a resource instance

Took me straight to the IPS package (representing the IPS IG) with the Condition Abatement Date extension definition listed. 
Finding a profile by description us core practitionerReturns the US Core package
Find a specific IGdeqmThe da vinci DEQM IG.
Examples and Extension definitions with the string "eye color" in iteye colorA number of packages where there were examples with the words "eye color" in them. Interestingly, "eye colour" - the UK spelling didn't return any results. 
Find a specific IG by canonical url

Returns a number of IG's - in this case US Core is the second. A number of other IG's refer to US Core
Find a CodeSystem by url the code system inside the IPS package. Clicking on the link in the summary took me into the description within the registry. 

API interface

The API interface performs similar functions to the UI, and is intended for application use.  


The search API is based on the NPM API rather than FHIR, as the idea of packages comes from NPM as stated in the beginning. It has the following url pattern:<parameters>.

Supported parameters are:

  • name - the package name. The query value can be in any part of the name.
  • canonical - the canonical url for a resource (of any type) within the package. The match is exact.
  • fhirversion - used as a filter to specify the FHIR version
  • prerelease - if true, then un released packages are included

Note that unlike the search through the UI - the API is a more direct string based query on a specific package element, and not one supported by elastic search.

Search results are a JSON array of objects with the following fields: 

  • name (ie the package name)
  • description 
  • FHIRVersion


The version API will return a list of all the versions for a given package.

If has the format<package-name>


The download API is also based on NPM. Its main purpose is to be able to download a package directly assuming you know the package name and version. (As noted above, you can also use NPM or Firely Terminal (ex Torinox).

It has the format<package-name>/<package-version> - for example

What's quite nice is that if you type this directly into a browser, it will prompt you to save the file locally. It's a tarball of course, so you'll need to expand it using zip or a similar application.

Adding a package to the registry

There are a number of different ways that a package can be added to the registry. One of these is free to use, while others are more automated, but may require a paid subscription. For example offers a free account which can publish a single package, for more than one you need an account.

If you only have a single package you wish to add to the repository, then the free account is probably the way to go.

If you have more than one, and do not have a account, then the manual process is likely the best - though it does involve a number of steps, and requires some technical expertise. 

The manual process


The manual process can be summarised  as follows.  

First time a package is to be added

  1. Create the package, and host it somewhere on the Internet where it can be retrieved (ie behind an HTTP server)
  2. Create an RSS feed that identifier and describes the packages you are authoring. Each package will have an item in the feed. The feed is updated manually when the package has changed. Place the feed somewhere on the Internet where it can be retrieved (ie behind an HTTP server)
  3. Add a reference to the list of feeds at
    1. Fork the repo into your own github account (button at upper right)
    2. In your forked copy of the repo, edit the file fhir-ig-list.json, and insert a reference to the feed you created in  step 2. Easiest is just to edit the file directly - just copy an existing feed entry and change to your values.
    3. Commit the changes. Select the option "Create a new branch and create pull request"
    4. Complete the pull request and save by clicking 'propose changes'

The pull request will be processed by an administrator of the original repo. If all goes well, the pull request will be accepted, and your feed will begin to be processed by the registry. This process of approving the request is a manual one, and so can take some time.

Subsequent updates

If this is an update to an existing package - ie a new version -  then simply update item in the feed (created in step 2 above). The registry will automatically update the package. This can take a few hours.

It is important to appreciate that once the unique combination between a package name and package version is found and imported by it will not be imported again, even if other details (like the contents of the linked file or metadata for the package in the feed) change. Only when a new version number is found for the same package will it be imported. This is important, because everyone should be able to trust that packages are fixed and will not change. That's one of the guarantees of packages, which allows us to build upon it and cache it ones in the registry or on your local computer.

If this is a new package, then create a new feed item and add to the feed. The registry will automatically add the package. This can take a few hours.


Notes on some of the steps:

1. Creating the package

As mentioned in the registry documentation, this can be done a number of ways, perhaps the easiest being to use the IGPublisher which creates the package with the name package.tgz. You might also want to check out FSH and Sushi as well as Forge to help with the artefact generation. There is also more information in the FHIR spec.

2. Create a feed and item/s.

This is an xml file like this:

<rss xmlns:dc="" xmlns:content="" xmlns:fhir="" xmlns:atom="" version="2.0">
	<title>My very own Packages</title>
	<description>New Packages published by me></description>
	<lastBuildDate>Wed, 21 Oct 2020 10:15:56 GMT</lastBuildDate>
	<atom:link href="" rel="self" type="application/rss+xml"/>
	<pubDate>Wed, 21 Oct 2020 10:15:56</pubDate>
		<description>A sample package</description>
		<guid isPermaLink="true"></guid>
		<dc:creator>John Doe</dc:creator>
		<pubDate>Mon, 19 Oct 2020 12:00:00 GMT</pubDate>

Most of the elements are self explanatory.

In the item:

  • The title is the package name and version
  • The link is the url where the package is located
  • The guid element is a copy of the package name (It is globally unique - or should be)

It needs to be accessible by the registry feed service.


The New FHIR Package Registry - Firely Blog



Zulip chat

  • No labels