Skip to content
Dennis Patterson edited this page Jun 4, 2019 · 18 revisions

Clinical Decision Support (CDS) Hooks is a specification that enables integration of remote decision support within a clinician's EHR workflow through a "hook"-based pattern. See more here.

This tutorial will help walk you through setting up real CDS Services and acting as the 3rd party providing decision support to an EHR system.

After completing this tutorial, you should be able to:

  • Understand the exchange between the EHR and 3rd party CDS Services
  • Stand up local CDS Services that can integrate with the CDS Hooks Sandbox
  • See how FHIR and SMART work within CDS Hooks

Define Terms

Before we dive in, we can define a few terms that will be used commonly throughout this tutorial.

hook - An event triggered by the EHR as part of the clinicians workflow. The EHR will invoke 3rd party CDS services registered to this event.

CDS Service - A 3rd party service set up to observe EHR activity. Specifically, this service listens for a specific hook to be invoked by the clinician. When the hook is invoked, the EHR calls upon this service, and the service may decide whether or not to respond with decision support back.

card - One type of response the CDS Service can give when called upon by the EHR. It is an entity containing all the information the CDS Service wants to display on the EHR. These cards can contain textual information, suggestions to add/remove/update FHIR resources (mostly pertaining to the patient), or even links to external web pages or SMART applications.

patient-view - A spec-defined hook where the clinician opens a patient's chart in the EHR

order-select - A spec-defined hook where a clinician selects one or more orders to place for a patient

sandbox - The CDS Hooks Sandbox web application that acts as a mock EHR. With this tool, you can simulate opening a patient's chart and prescribing a medication with a patient in context. Additionally, you can configure your own CDS Services to test functionality as if being invoked by a real EHR system. You can reach the sandbox at


Our goal of this tutorial is to set up two services that respond to the patient-view and order-select hook respectively through a server-side application. We will test these services using the CDS Hooks Sandbox. Let's define the scenarios for each service, and what our services should do.

patient-view-example: Invoked by the patient-view hook, this service should simply prefetch the Patient FHIR resource for the patient in context of the EHR and display a message on a card with the patient's first and last name. Additionally, this service will add a link on the card with the URL to the CDS Hooks spec.

order-select-example: Invoked by the order-select hook, this service should read the FHIR context the EHR provides (order being selected), and display a suggestion (button) to switch a medication to Aspirin 81 MG Oral Tablet. If the order selected is that specific Aspirin we want to suggest, or the provider has "clicked" on the suggestion already, the service will provide a message on a card confirming their order choice.


The following are necessary to work with this tutorial application:

  • Git installed on your machine
  • A Github account created
  • Either a Node.js or Docker environment installed and available, per the sections below


This option works well if you have a recent Node.js installation or want to use Node.js tooling directly in the tutorial.

  • Node.js (min. v8.4.0) installed on machine
    • To make sure it's ready to use, open your command prompt or terminal console and type the command node -v which should respond with the Node.js version installed on the machine
    • If you are having some trouble with installing/updating Node.js, see the FAQ.


This option works well if you have an older (or non-existent) Node.js installation and/or want to use an ephemeral container environment to run the tutorial.

  • Follow Docker's installation guide for your OS.
    • Verify command line availability by running docker -v
  • Follow Docker Compose's installation guide for your OS if it wasn't already installed as part of the previous step.
    • Verify command line availability by running docker-compose -v

Project Overview

Let's go over some important files and tools in this project:

package.json - Here is where the metadata for the project lives. This contains the dependencies required for this project as well as the scripts used to run our application. You can read more about this file here.

index.js - This is where our application logic lives. This file sets up app configuration and how to respond to specific GET and POST requests to our CDS Service routes.

We will use Node.js for this project, which allows us to write server-side logic in JavaScript to handle HTTP requests to our server. To simplify this, we will use the Express framework, which is a Node.js web application framework that contains several HTTP utility methods and middleware to use.

Project Setup

Once you have completed all the prerequisites, it's time to setup the project locally on your machine. Complete the following steps:

  1. Login to your Github account and navigate to the tutorial repository.
  2. Clone the repository down to your machine using the following steps:
    • In your command prompt or terminal, navigate to the folder you would like your local copy of the repository to live
    • Once you're at the location in your file system, type the following command to clone the local copy of the repository to your machine:

      git clone

    • Navigate inside the local cds-service-tutorial repository folder on your command prompt or terminal

Running the project

Depending on your tool choice, use one of the following methods to start the project:

  • Node.js
    • Once you're inside the project directory, type the command npm install to install all dependencies for the project.
    • If the above steps have all been done successfully, you can run the project by typing the command npm run start-server.
  • Docker
    • Once you're inside the project directory, type the command docker-compose up --build to build the image and start the container.

This will start the express application, which will be hosted locally for you, and can be accessible at:


Docker Cleanup

  • The container can be stopped by breaking with Ctrl-C.
  • To remove the container and image from your machine, type the command docker-compose down --rmi all.

How it Works

Let's look at how this application starts up. Begin by looking inside the project directory at the index.js file, which is where all the host code for our Express application lives. You can open up this file with any text editor of your choice and walk through the code for this tutorial.

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

The first 2 lines of code are creating variables that reference two very important dependencies. We pulled these dependencies in via the command npm install from above.

  • express - As we mentioned above, Express is a framework for Node.js which allows us to use several HTTP methods to handle routing, as well as middleware.
  • body-parser - This dependency is a middleware necessary to parse the body of an incoming request; specifically, from POST requests. This allows the application to get data the EHR may send in a POST request to our CDS Services.

On that last line above, we construct an Express instance in a variable called app that will expose the Express API that we can use throughout our application.

At this point, we can define a middleware that will parse incoming request bodies to our services as JSON, for those potential POST HTTP requests.


And finally, we need to allow the app to be hosted on some port, so let's define this app to listen in at port 3000 for the purposes of this tutorial. We can define this at the bottom of the application.


Next step: Cross Origin Resource Sharing (CORS)