npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

onfhir

v1.0.3

Published

A TypeScript client for interacting with FHIR servers.

Readme

🔥OnFHIR

A lightweight TypeScript library for interacting with FHIR servers using OAuth 2.0 SMART on FHIR authentication flow.

NodeJS and Browser compatible.

Features

  • OAuth 2.0 SMART on FHIR Authentication 🔒 - Complete authorization flow with automatic token refresh
  • Type-Safe FHIR Operations 📜 - Full TypeScript support with FHIR resource types
  • Multi-Version Support 🌐 - Works with FHIR DSTU2, STU3, R4, and R5
  • Automatic Pagination 📄 - Transparently handles FHIR bundle pagination
  • Patient-Scoped Operations 🩺 - Built-in patient context management
  • Error Handling ⚠️ - Descriptive errors for authentication and server issues
  • Lightweight ⚙️ - Minimal dependencies for easy integration

Installation

npm install onfhir

or

yarn add onfhir

Quick Start

Creating a Client

import Client from 'onfhir';

// Create a client
const client = new Client({
  baseUrl: 'http://hapi.fhir.org/baseR5',
});

// Get FHIR version info
const version = await client.getFhirVersion(); // "5.0.0"
const release = await client.getFhirRelease(); // 5

Client Options

| Parameter | Type | Required | Description | | :------------- | :----- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | baseUrl | string | ✓ | FHIR server base URL (e.g., https://hapi.fhir.org/baseR4) | | clientId | string | | OAuth 2.0 client identifier | | clientSecret | string | | OAuth 2.0 client secret | | refreshToken | string | | Token for refreshing expired access tokens, for resuming previous session | | scope | string | | Space-separated OAuth scopes (e.g., launch/patient openid fhirUser offline_access) | | patientId | string | | FHIR patient ID for patient-scoped operations |

Authentication

// Redirect user to authorization URL
const url = await authorize({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  redirectUri: 'your-redirect-uri',
  scope: 'your-scope',
  iss: 'your-fhir-server-url',
});

// After redirect, complete authentication
const client = await completeAuth(window.location.href);
// Alternatively, create client with existing refresh token
const client = await Client({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  refreshToken: 'your-refresh-token',
});

Patient-Scoped Operations

// Access patient context
const patientId = client.patient.id;

// Patient-scoped operations
const medications = await client.patient.read('Medication');
const observations = await client.patient.read('Observation');

General Resource Operations

// Read a resource
const patient = await client.read('Patient');
console.log(patient);

// Search resources
const patients = await client.read('Patient', { name: 'John' });
console.log(patients);

API Reference

Functions

authorize(options)

Initiates the OAuth 2.0 SMART on FHIR authorization flow.

authorize({
  clientId: string;
  clientSecret: string;
  redirectUri: string;
  scope: string;
  iss: string; // FHIR server URL
}): Promise<string> // Authorization URL

completeAuth(path, unsafeUrlEncode?)

Completes the authorization flow by exchanging the auth code for tokens.

completeAuth(
  path: string, // Request path with query params
  unsafeUrlEncode?: boolean
): Promise<Client>

fetchMetadata(serverUrl)

Fetches the FHIR server's CapabilityStatement.

fetchMetadata(serverUrl: string): Promise<CapabilityStatement>

getSecurityExtensions(serverUrl)

Extracts OAuth 2.0 endpoints from the server's CapabilityStatement.

getSecurityExtensions(serverUrl: string): Promise<{ [key: string]: string }>

Client Class

Constructor

new Client({
  baseUrl: string;
  clientId: string;
  clientSecret: string;
  refreshToken: string;
  scope?: string;
  patientId?: string;
})

Properties

  • accessToken: string - Current access token
  • refreshToken: string - Refresh token for obtaining new access tokens
  • expiresAt: number - Timestamp when access token expires
  • patient - Object with patient-scoped methods

Methods

  • read(path, options?) - GET request (Auto-refreshes tokens if needed)
  • create(path, options?) - POST request
  • update(path, options?) - PUT request
  • delete(path, options?) - DELETE request
  • refresh() - Manually refresh the access token
  • getFhirVersion() - Get server's FHIR version string
  • getFhirRelease() - Get numeric FHIR release (2, 3, 4, 5)

Note: options are Axios request config overrides.

FHIR Version Mapping

| FHIR Version | Release | | :------------ | --------: | | 0.4.0 - 1.0.2 | 2 (DSTU2) | | 1.1.0 - 3.0.1 | 3 (STU3) | | 3.3.0 - 4.0.1 | 4 (R4) | | 4.0.1+ | 5 (R5) |

Automatic Token Refresh

The client automatically refreshes expired access tokens before making requests. You don't need to manually check token expiration.

// This will automatically refresh if token is expired
const data = await client.read('Patient/123');

// Access the refreshed access token
console.log(client.accessToken);

// Manually refresh the token if needed
await client.refresh();

Pagination

Bundle responses with multiple pages are automatically paginated. When flat: true, all entries across pages are flattened into a single array.

// Automatically follows "next" links and returns all resources
const allPatients = await client.read('Patient', { _count: 100 });

Error Handling

The library throws descriptive errors for authentication failures and server errors:

try {
  const client = await Client({
    clientId: 'invalid-client-id',
    clientSecret: 'invalid-client-secret',
  });
} catch (error) {
  console.error(error.message); // "access_denied: User denied"
}

License

MIT

Contributing

Contributions are welcome! Please open issues and pull requests on GitHub.