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

cms1500-react

v1.2.1

Published

Production-ready React library for rendering, filling, and printing CMS-1500 (HCFA) claim forms via PDF with FHIR-compatible input

Readme

cms1500-react

Production-ready React library for filling, rendering, and printing CMS-1500 (HCFA) claim forms. Uses pdf-lib to fill actual PDF form fields for pixel-perfect output. FHIR R4 compatible, HIPAA-conscious design.

How It Works

Unlike CSS-overlay approaches, this library fills the actual form fields in a CMS-1500 PDF template using pdf-lib. This means:

  • Pixel-perfect alignment — fields snap to the PDF's own coordinates
  • Real PDF output — can be saved, emailed, uploaded, or printed
  • Works with any standard CMS-1500 (02/12) editable PDF template

Install

npm install cms1500-react pdf-lib

Peer dependencies: react >= 17, react-dom >= 17

Zero Config — PDF Template Included

The CMS-1500 PDF template is bundled inside the package. No file copying, no public directory setup, no URL configuration. Just install and use — it works out of the box.

Quick Start

1. Component Usage

import { CMS1500Form } from 'cms1500-react';

function ClaimPage({ claimData }) {
  return (
    <CMS1500Form
      data={claimData}
      width="100%"
      height="calc(100vh - 120px)"
    />
  );
}

2. Hook Usage (with print/download)

import { useCMS1500 } from 'cms1500-react';

function ClaimPage({ claimData }) {
  const { pdfUrl, loading, generatePdf, handlePrint, handleDownload, iframeRef } =
    useCMS1500();

  useEffect(() => { generatePdf(claimData); }, []);

  return (
    <div>
      <button onClick={handlePrint}>Print</button>
      <button onClick={() => handleDownload('claim.pdf')}>Download</button>
      {pdfUrl && (
        <iframe ref={iframeRef} src={pdfUrl} style={{ width: '100%', height: '80vh' }} />
      )}
    </div>
  );
}

3. Headless PDF Generation (no React)

import { fillCMS1500Pdf, getEmbeddedTemplate } from 'cms1500-react';

// Template is bundled — no fetch needed
const templateBytes = getEmbeddedTemplate();
const filledPdf = await fillCMS1500Pdf(templateBytes, claimData);
// filledPdf is a Uint8Array — save to file, upload, etc.

Data Shape (CMS1500Data)

All fields are optional — pass only what you need. The JSON below shows every supported field with descriptions:

{
  // ─── CARRIER / INSURANCE (Top of form) ───
  "insuranceType": "group_health",          // "medicare" | "medicaid" | "tricare" | "champva" | "group_health" | "feca_blk_lung" | "other"
  "insuranceId": "XYZ123456789",            // Box 1a: Insured's ID number
  "patientInsurance": {                     // Insurance plan details
    "planName": "BCBS PPO",
    "policyNumber": "GRP-001234",
    "address": {
      "line1": "PO Box 100",
      "line2": "Suite 200",                // Optional
      "city": "Chico",
      "state": "CA",
      "zipcode": "95927"
    },
    "phoneNumber": "5559876543",
    "dob": "1980-01-15",                   // Insured's DOB (YYYY-MM-DD)
    "sex": "M"                             // "M" | "F"
  },

  // ─── PATIENT INFO (Boxes 2-5) ───
  "patientName": "JOHN DOE",               // Box 2: Patient's full name
  "patientDOB": "1980-01-15",              // Box 3: DOB (YYYY-MM-DD)
  "patientSex": "M",                       // Box 3: "M" | "F"
  "patientAddress": {                       // Box 5: Patient address
    "line1": "123 Main St",
    "line2": "Apt 4B",                     // Optional
    "city": "Anytown",
    "state": "CA",
    "zipcode": "90210"
  },
  "patientPhone": "(555) 123-4567",        // Box 5: Patient phone

  // ─── INSURED INFO (Boxes 4, 6-7, 11) ───
  "insuredName": "JOHN DOE",               // Box 4: Insured's name (defaults to plan name if omitted)
  "patientRelationship": "Self",            // Box 6: "Self" | "Spouse" | "Child" | "Other"

  // ─── OTHER INSURED (Box 9) ───
  "otherInsuredName": "JANE DOE",           // Box 9: Other insured's name
  "otherInsuredPolicy": "POL-5678",         // Box 9a: Other insured's policy number
  "otherInsuredPlanName": "AETNA HMO",      // Box 9d: Other insured's plan name

  // ─── CONDITION (Box 10) ───
  "conditionRelatedTo": {                   // Box 10: Is condition related to...
    "employment": false,                    // 10a: Employment
    "autoAccident": false,                  // 10b: Auto accident
    "autoAccidentState": "CA",              // 10b: State (if auto accident)
    "otherAccident": false                  // 10c: Other accident
  },

  // ─── SIGNATURES (Boxes 12-13) ───
  "patientSignature": "SIGNATURE ON FILE",  // Box 12: Patient signature
  "patientSignatureDate": "2026-03-15",     // Box 12: Date signed
  "insuredSignature": "SIGNATURE ON FILE",  // Box 13: Insured's signature

  // ─── DATES (Boxes 14-16, 18) ───
  "dateOfCurrentIllness": "2026-03-10",     // Box 14: Date of current illness (YYYY-MM-DD)
  "dateOfSimilarIllness": "2025-06-20",     // Box 15: Similar illness date (YYYY-MM-DD)
  "unableToWorkFrom": "2026-03-10",         // Box 16: Unable to work from (YYYY-MM-DD)
  "unableToWorkTo": "2026-03-17",           // Box 16: Unable to work to (YYYY-MM-DD)
  "hospitalizationFrom": "2026-03-11",      // Box 18: Hospitalization from (YYYY-MM-DD)
  "hospitalizationTo": "2026-03-13",        // Box 18: Hospitalization to (YYYY-MM-DD)

  // ─── PROVIDER INFO (Boxes 17, 19-20) ───
  "referringProvider": { "1": "SMITH, JANE MD" },  // Box 17: Referring provider name
  "referringProviderNPI": "1234567890",     // Box 17b: Referring provider NPI
  "referringProviderOtherId": "G1234567",   // Box 17a: Other ID
  "additionalClaimInfo": "Initial treatment",// Box 19: Additional claim info
  "outsideLab": false,                      // Box 20: Outside lab?
  "outsideLabCharges": 0,                   // Box 20: Lab charges ($)
  "nuccUse": "",                            // NUCC Use field

  // ─── DIAGNOSIS (Box 21, A-L, up to 12) ───
  "diagnisisCodeData": [
    { "code": "J06.9" },                   // A: Acute upper respiratory infection
    { "code": "R05.9" },                   // B: Cough
    { "code": "J20.9" },                   // C: Acute bronchitis
    { "code": "R50.9" }                    // D: Fever (up to 12 codes: A-L)
  ],

  // ─── RESUBMISSION / AUTH (Boxes 22-23) ───
  "resubmissionCode": "7",                 // Box 22: Resubmission code
  "originalRefNumber": "ORIG-12345",        // Box 22: Original reference number
  "priorAuthorization": "AUTH-2026-0042",   // Box 23: Prior authorization number

  // ─── SERVICE LINES (Box 24, up to 6 lines) ───
  "dateOfService": "2026-03-15",            // Date of service for all lines (YYYY-MM-DD)
  "posCode": "11",                          // Place of service code (11 = Office)
  "renderingProviderNPI": "9876543210",     // Rendering provider NPI for all lines
  "patientProcedureCodes": [
    {
      "procedureCode": { "1": "99213-Office Visit" },      // CPT code (code-description format)
      "modifiers": { "1": "25-Significant E/M" },          // Up to 4 modifiers
      "diagnosisFirstPointers": "A",        // Diagnosis pointer (references Box 21)
      "diagnosisSecondPointers": "B",       // Optional second pointer
      "diagnosisThirdPointers": "",         // Optional third pointer
      "diagnosisFourthPointers": "",        // Optional fourth pointer
      "charges": 150.00,                    // Line charges ($)
      "quantity": 1,                        // Units/days
      "epsdt": "",                          // EPSDT/Family Plan
      "typeOfService": ""                   // Type of service
    },
    {
      "procedureCode": { "1": "99214-Office Visit Extended" },
      "modifiers": {},
      "diagnosisFirstPointers": "A",
      "charges": 250.00,
      "quantity": 1
    }
  ],

  // ─── PROVIDER / BILLING (Boxes 25-33) ───
  "federalTaxId": "12-3456789",            // Box 25: Federal Tax ID
  "federalTaxIdType": "EIN",               // Box 25: "SSN" | "EIN"
  "patientAccountNumber": "ACCT-001234",    // Box 26: Patient account number
  "acceptAssignment": true,                 // Box 27: Accept assignment?
  "total": 400.00,                          // Box 28: Total charge ($)
  "amountPaid": 50.00,                      // Box 29: Amount paid ($)

  "physicianSignature": "SIGNATURE ON FILE",// Box 31: Physician signature
  "physicianSignatureDate": "2026-03-15",   // Box 31: Date

  "serviceLocation": { "1": "ANYTOWN MEDICAL CENTER" },  // Box 32: Service facility name
  "serviceFacilityName": "ANYTOWN MEDICAL CENTER",        // Box 32: Facility name
  "serviceFacilityAddress": "456 Health Blvd, Anytown CA 90210", // Box 32: Facility address

  "billingProvider": { "1": "ANYTOWN MEDICAL GROUP" },    // Box 33: Billing provider name
  "billingProviderName": "ANYTOWN MEDICAL GROUP",          // Box 33: Provider name
  "billingProviderAddress": "789 Billing Ave, Anytown CA 90210", // Box 33: Provider address
  "billingProviderPhone": "(555) 987-6543",                // Box 33: Phone
  "billingProviderNPI": "1112223334",       // Box 33a: Billing provider NPI
  "billingProviderGroupNPI": "5556667778"   // Box 33b: Group NPI
}

Minimal Example

Only a few fields are needed to generate a basic claim:

{
  "patientName": "JOHN DOE",
  "patientDOB": "1980-01-15",
  "patientSex": "M",
  "insuranceId": "XYZ123456789",
  "diagnisisCodeData": [{ "code": "J06.9" }],
  "dateOfService": "2026-03-15",
  "posCode": "11",
  "patientProcedureCodes": [
    {
      "procedureCode": { "1": "99213" },
      "diagnosisFirstPointers": "A",
      "charges": 150.00,
      "quantity": 1
    }
  ],
  "total": 150.00
}

FHIR R4 Mapping

import { mapFHIRToCMS1500 } from 'cms1500-react';
import type { FHIRClaimBundle } from 'cms1500-react';

const bundle: FHIRClaimBundle = {
  patient: {
    resourceType: 'Patient',
    name: [{ family: 'Doe', given: ['John'] }],
    birthDate: '1980-01-15',
    gender: 'male',
  },
  claim: {
    resourceType: 'Claim',
    diagnosis: [
      { sequence: 1, diagnosisCodeableConcept: { coding: [{ code: 'J06.9' }] } },
    ],
    item: [
      {
        sequence: 1,
        productOrService: { coding: [{ code: '99213' }] },
        servicedDate: '2026-03-15',
        locationCodeableConcept: { coding: [{ code: '11' }] },
        quantity: { value: 1 },
        net: { value: 150.00 },
        diagnosisSequence: [1],
      },
    ],
  },
};

const formData = mapFHIRToCMS1500(bundle);

Migrating from CMSForm.tsx

Replaces ~545 lines of inline pdf-lib logic, manual field mapping, and PDF fetching with a single component:

// BEFORE: CMSForm.tsx — manual pdf-lib, fetch template, 200+ field mappings
import { PDFDocument, StandardFonts } from "pdf-lib";
const existingPdfBytes = await fetch("/cms-form/form-cms-1500.pdf").then(res => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const customFont = await pdfDoc.embedStandardFont(StandardFonts.CourierBold);
const form = pdfDoc.getForm();
// ... 200+ lines of form.getTextField(...).setText(...)

// AFTER: Just this — PDF template is bundled, all mapping handled internally
import { CMS1500Form } from 'cms1500-react';

<CMS1500Form
  data={disclosureHost.data}  // Same prefillData shape — no changes needed
  width="90vw"
  height="calc(100svh - 120px)"
/>

No PdfViewDrawer, no useGetMMDDYY, no getModifier, no getDiagnosis, no cms1500DummyPrefill — all handled by the package.

API Reference

<CMS1500Form />

| Prop | Type | Default | Description | |------|------|---------|-------------| | data | CMS1500Data | required | Form data | | pdfTemplateUrl | string | Built-in (bundled) | Optional custom PDF template URL. Uses embedded template by default | | onPdfReady | (url: string) => void | — | Called when PDF is generated | | onError | (error: Error) => void | — | Called on error | | width | string \| number | '100%' | Viewer width | | height | string \| number | 'calc(100vh - 120px)' | Viewer height | | autoGenerate | boolean | true | Auto-generate on mount | | className | string | — | CSS class | | style | CSSProperties | — | Inline styles |

useCMS1500(options?)

| Return | Type | Description | |--------|------|-------------| | pdfUrl | string \| null | Blob URL of generated PDF | | loading | boolean | Generation in progress | | error | Error \| null | Last error | | generatePdf | (data) => Promise<string \| null> | Generate PDF | | handlePrint | () => void | Print the PDF | | handleDownload | (filename?) => void | Download the PDF | | iframeRef | RefObject<HTMLIFrameElement> | Ref for iframe | | cleanup | () => void | Revoke blob URL |

fillCMS1500Pdf(pdfBytes, data, options?)

Low-level function — fill a PDF template and get back Uint8Array. Works without React (Node.js, workers, etc).

mapFHIRToCMS1500(bundle)

Maps FHIRClaimBundleCMS1500Data.

HIPAA Compliance

This library is designed with HIPAA (Health Insurance Portability and Accountability Act) compliance in mind. It supports the Privacy Rule, Security Rule, and Minimum Necessary Standard by ensuring that Protected Health Information (PHI) is handled securely at every step.

How This Library Supports HIPAA

Zero PHI Footprint

| Safeguard | How It's Enforced | |-----------|-------------------| | No data storage | All data is passed via props and held only in memory — nothing is written to disk | | No logging of PHI | No console.log, console.debug, or telemetry captures patient data | | No network transmission | The library makes zero outbound API calls — only fetches the blank PDF template | | No persistence | No localStorage, sessionStorage, cookies, or IndexedDB usage | | No third-party data sharing | No analytics, tracking pixels, or external SDKs are loaded | | Client-side only | PDF generation happens entirely in the browser using pdf-lib — PHI never leaves the client | | Stateless rendering | No internal state retains PHI beyond the current render cycle |

HIPAA Technical Safeguards Alignment

| HIPAA Requirement | Library Support | |-------------------|-----------------| | Access Control (§164.312(a)) | Library is stateless — access control is enforced at your application layer (auth/RBAC) | | Audit Controls (§164.312(b)) | No PHI is logged internally; your app can log access events (who viewed/printed/downloaded) | | Integrity Controls (§164.312(c)) | PDF is generated from structured data using pdf-lib — no manual field manipulation or injection risk | | Transmission Security (§164.312(e)) | Library operates client-side only; serve your app over HTTPS to encrypt data in transit | | Minimum Necessary (§164.502(b)) | Only the fields required for CMS-1500 are accepted and rendered — no extraneous PHI processing |

PHI Data Flow

Your App (authenticated) → Props → cms1500-react → pdf-lib → Browser Memory → Print/Download
                                    ↑                                ↑
                              No disk writes                  No server calls
                              No logging                      No persistence

Recommended Practices for HIPAA-Compliant Deployment

  1. Authentication & Authorization — Gate form access behind role-based access control (RBAC). Only authorized users (billing staff, providers) should view claim forms.
  2. Audit Logging — Log access events in your application layer: who viewed, printed, or downloaded each claim form, and when.
  3. HTTPS Only — Always serve your application over TLS/HTTPS to protect PHI in transit.
  4. Session Timeout — Auto-timeout sessions displaying PHI after a period of inactivity (recommended: 15 minutes per HIPAA best practices).
  5. Cache Control — Set Cache-Control: no-store and Pragma: no-cache headers for pages rendering PHI to prevent browser caching.
  6. Secure Print Handling — Educate users on secure handling of printed CMS-1500 forms (physical safeguard).
  7. BAA Coverage — If using this library in a SaaS product, ensure your hosting provider is covered under a Business Associate Agreement (BAA).
  8. Incident Response — Have a breach notification plan in place as required by the HIPAA Breach Notification Rule (§164.400-414).

Compliance Disclaimer

This library is designed to support HIPAA compliance but does not guarantee it on its own. HIPAA compliance is a holistic requirement covering administrative, physical, and technical safeguards across your entire application stack. You are responsible for implementing appropriate access controls, audit logging, encryption, and organizational policies in your deployment environment.

License

MIT