https://github.com/dnlbox/fhir-capability-analyzer
CLI and library for fetching, analyzing, and comparing FHIR server CapabilityStatements. Profile detection for US Core, UK Core, AU Core, IPS, ISiK and more.
https://github.com/dnlbox/fhir-capability-analyzer
capability-statement cli fhir fhir-r4 fhir-r4b fhir-r5 health-interoperability healthcare hl7 ips r4b typescript us-core
Last synced: about 1 month ago
JSON representation
CLI and library for fetching, analyzing, and comparing FHIR server CapabilityStatements. Profile detection for US Core, UK Core, AU Core, IPS, ISiK and more.
- Host: GitHub
- URL: https://github.com/dnlbox/fhir-capability-analyzer
- Owner: dnlbox
- License: mit
- Created: 2026-04-19T14:09:45.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-20T20:51:05.000Z (about 1 month ago)
- Last Synced: 2026-05-20T21:47:46.320Z (about 1 month ago)
- Topics: capability-statement, cli, fhir, fhir-r4, fhir-r4b, fhir-r5, health-interoperability, healthcare, hl7, ips, r4b, typescript, us-core
- Language: TypeScript
- Homepage: https://dnlbox.github.io/fhir-capability-analyzer/
- Size: 313 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# fhir-capability-analyzer
[](https://github.com/dnlbox/fhir-capability-analyzer/actions/workflows/ci.yml)
[](https://github.com/dnlbox/fhir-capability-analyzer/actions/workflows/codeql.yml)
[](https://www.npmjs.com/package/fhir-capability-analyzer)
[](LICENSE)
A TypeScript CLI and library that answers the question: **"What does this FHIR server actually support?"**
- Fetch a CapabilityStatement from any FHIR server URL or local JSON file
- Summarize resources, interactions, operations, and security in a readable format
- Detect conformance to international profiles: US Core, UK Core, AU Core, IPS, IPA, SMART App Launch, ISiK, and more
- Generate a structured analysis report with warnings for common configuration issues
- Compare two servers' capabilities side by side
- Output as human-readable text, JSON (CI-friendly), or Markdown
The browser-safe core works in Node.js, Deno, Cloudflare Workers, and browser bundles. The CLI wraps the same core with file I/O and exit codes.
## Why this exists
Every FHIR server exposes a CapabilityStatement at `/metadata` describing every resource, interaction, search parameter, and security mechanism it supports. Reading one by hand is painful: a typical document runs 1,000 to 3,000 lines of deeply nested JSON.
`fhir-capability-analyzer` does that reading for you: fetch, parse, summarize, and compare, all from the command line. It also detects which international profiles a server declares support for, which is useful when integrating with servers in different countries or healthcare systems.
## Quick start
```bash
# Analyze a live server
npx fhir-capability-analyzer analyze https://hapi.fhir.org/baseR4
# Analyze a local file
npx fhir-capability-analyzer analyze ./capability.json
# JSON output (CI-friendly, stable schema)
npx fhir-capability-analyzer analyze https://hapi.fhir.org/baseR4 --format json
# Markdown output
npx fhir-capability-analyzer analyze https://hapi.fhir.org/baseR4 --format markdown
# Compare two servers
npx fhir-capability-analyzer compare https://server-a.example.com https://server-b.example.com
# Compare and fail CI if differences found
npx fhir-capability-analyzer compare ./baseline.json https://server.example.com --exit-on-diff
```
## Sample output
```txt
Server: HAPI FHIR R4 Test Server
FHIR Version: 4.0.1
Status: active
Formats: application/fhir+json, application/fhir+xml, json, xml
Resources (3)
-------------
Patient read, vread, update, patch, delete, history-instance, history-type, create, search-type [7 search params]
Observation read, create, update, delete, search-type [4 search params]
Condition read, create, update, search-type [3 search params]
Operations (2)
--------------
$everything
$validate
Profile Conformance
-------------------
(No known profiles detected)
Security
--------
CORS: enabled
Auth: (none declared)
```
## Installation
```bash
# Global CLI
npm install -g fhir-capability-analyzer
# Project dependency (library use)
npm install fhir-capability-analyzer
```
## CLI reference
### `analyze `
Analyze a CapabilityStatement from a URL or local JSON file.
```bash
Arguments:
source FHIR server URL or path to local JSON file
Options:
-f, --format Output format: text | json | markdown (default: text)
--bearer-token Bearer token for OAuth 2.0 protected servers
-v, --version Print version
-h, --help Show help
Exit codes:
0 Success, no warnings
1 Success, but warnings were found (text and markdown modes only)
2 Fetch or parse error
```
### `compare `
Compare two FHIR servers' capabilities.
```bash
Arguments:
sourceA FHIR server URL or local JSON file (baseline)
sourceB FHIR server URL or local JSON file (target)
Options:
-f, --format Output format: text | json | markdown (default: text)
--exit-on-diff Exit with code 1 when differences are found
--bearer-token Bearer token for OAuth 2.0 protected servers
-h, --help Show help
```
### Authentication
For OAuth 2.0 protected servers, pass the token via flag or environment variable:
```bash
# Via flag
fhir-capability-analyzer analyze https://secure.example.com --bearer-token "$TOKEN"
# Via environment variable (preferred for CI β keeps the token out of shell history)
FHIR_TOKEN=eyJ... fhir-capability-analyzer analyze https://secure.example.com
# Compare two secured servers (same token used for both)
FHIR_TOKEN=eyJ... fhir-capability-analyzer compare https://server-a.example.com https://server-b.example.com
```
The `--bearer-token` flag takes precedence over `FHIR_TOKEN`. Tokens are never written to stdout or included in any output format.
## TypeScript library API
```typescript
import {
fetchCapabilityStatement,
parseFromJson,
analyze,
compare,
} from "fhir-capability-analyzer";
import { detectProfiles } from "fhir-capability-analyzer/registry";
// Fetch from a live server
const result = await fetchCapabilityStatement("https://hapi.fhir.org/baseR4");
// Fetch from an OAuth 2.0 protected server
const result = await fetchCapabilityStatement("https://secure.example.com", {
headers: { Authorization: `Bearer ${token}` },
});
if (!result.success) throw new Error(result.error);
// Analyze
const report = analyze(result.capability);
console.log(report.summary.resourceCount); // number of resources
console.log(report.conformance.detectedProfiles); // ProfileConformance[]
console.log(report.warnings); // string[]
// Parse from local JSON (e.g., after fs.readFileSync)
const localResult = parseFromJson(JSON.parse(rawJson));
// Compare two capabilities
const diff = compare(capA, capB);
// diff.added, diff.removed, diff.changed β ComparisonDifference[]
// Profile detection only
const profiles = detectProfiles([
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient",
]);
// [{ url, name, country, standard }]
```
## Profile detection
Detects conformance to known international and national FHIR profiles by matching profile URLs declared in `instantiates`, `implementationGuide`, and per-resource `profile`/`supportedProfile` fields.
| Standard | Country | Canonical URL prefix |
| ---------------- | ---------------- | ---------------------------------------------------------------------------------- |
| US Core | πΊπΈ us | `http://hl7.org/fhir/us/core/` |
| UK Core | π¬π§ uk | `https://fhir.hl7.org.uk/`, `https://fhir.nhs.uk/` |
| AU Core | π¦πΊ au | `http://hl7.org.au/fhir/core/` |
| AU Base | π¦πΊ au | `http://hl7.org.au/fhir/` |
| CA Baseline | π¨π¦ ca | `http://hl7.org/fhir/ca/baseline/` |
| IPS | π international | `http://hl7.org/fhir/uv/ips/` |
| IPA | π international | `http://hl7.org/fhir/uv/ipa/` |
| SMART App Launch | π international | `http://fhir-registry.smarthealthit.org/`, `http://hl7.org/fhir/smart-app-launch/` |
| ISiK | π©πͺ de | `https://gematik.de/fhir/isik/`, `https://gematik.de/fhir/ISiK/` |
| FR Core | π«π· fr | `http://hl7.org/fhir/fr/core/`, `https://hl7.fr/ig/fhir/` |
| NL Nictiz | π³π± nl | `http://nictiz.nl/fhir/` |
| IHE | π international | `https://profiles.ihe.net/` |
These are FHIR canonical identifiers. Some canonical URL hosts do not resolve in a browser,
but the identifiers still need to be matched exactly when they appear in a CapabilityStatement.
## Architecture
```md
src/core/ browser-safe functional core
types.ts all shared TypeScript interfaces
parse.ts CapabilityStatement β ServerCapability
fetch.ts fetch from URL, parse from JSON
analyze.ts ServerCapability β AnalysisReport
compare.ts ServerCapability Γ ServerCapability β ComparisonReport
src/registry/ browser-safe profile registry
profiles.ts known profile URL patterns
detect.ts detectProfiles(urls[]) β ProfileConformance[]
src/formatters/ browser-safe output renderers
text.ts human-readable text
json.ts stable JSON
markdown.ts Markdown tables
src/cli/ Node.js adapter (thin shell over core)
commands/ analyze.ts, compare.ts
```
No code under `src/core/`, `src/registry/`, or `src/formatters/` imports Node.js APIs. This is enforced by TypeScript and tested.
## What this tool does NOT do
- Full StructureDefinition / profile conformance validation β use the [HL7 FHIR Validator](https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator)
- Profile evaluation beyond URL pattern matching (only checks declared URLs, not resource content)
- OAuth 2.0 authorization flows β you need to obtain a bearer token separately and pass it via `--bearer-token` or `FHIR_TOKEN`
- IG package resolution or download
- XML to JSON conversion β use the [`fhir`](https://www.npmjs.com/package/fhir) package
## Supported FHIR versions
R4 (4.0.1), R4B (4.3.0), R5 (5.0.0) β auto-detected from the `fhirVersion` field.
## The FHIR TypeScript ecosystem
`fhir-capability-analyzer` is part of a small family of tools for FHIR developer workflows:
| Tool | Purpose |
|---|---|
| [`fhir-resource-diff`](https://github.com/dnlbox/fhir-resource-diff) | Validate, diff, and compare individual FHIR JSON resources |
| [`fhir-test-data`](https://github.com/dnlbox/fhir-test-data) | Generate valid FHIR test data with country-aware identifiers (14 locales) |
| `fhir-capability-analyzer` (this package) | Fetch, analyze, and compare FHIR server CapabilityStatements |
**Using them together:**
```bash
# Check what a server supports before running integration tests
fhir-capability-analyzer analyze https://your-fhir-server.example.com
# Generate test patients and validate them against the FHIR spec
fhir-test-data generate patient --locale uk --seed 42 | \
fhir-resource-diff validate - --fhir-version R4
# Compare two servers to find differences before a migration
fhir-capability-analyzer compare https://old-server.example.com https://new-server.example.com \
--exit-on-diff
```
## Development
### Prerequisites
- Node.js >= 20
- pnpm >= 9
### Setup
```bash
git clone https://github.com/dnlbox/fhir-capability-analyzer.git
cd fhir-capability-analyzer
pnpm install
```
### Common scripts
| Script | Purpose |
|--------|---------|
| `pnpm cli -- analyze ` | Run CLI from source |
| `pnpm test` | Run tests |
| `pnpm test:watch` | Run tests in watch mode |
| `pnpm typecheck` | TypeScript type checking |
| `pnpm lint` | ESLint |
| `pnpm build` | Production build (tsup) |
## Roadmap
- [x] Authentication support for secured FHIR servers (OAuth 2.0 token injection)
- [ ] `--assert` flag for CI: fail if a specific profile is not detected
## Links
- [Documentation](https://dnlbox.github.io/fhir-capability-analyzer/)
- [npm](https://www.npmjs.com/package/fhir-capability-analyzer)
- [GitHub](https://github.com/dnlbox/fhir-capability-analyzer)
- [FHIR specification](https://hl7.org/fhir/)