Free, open-source medical bill checker that runs entirely in your browser.
Upload a PDF medical bill and BillRx scans it for overcharges, duplicate charges, math errors, and suspicious fees, then helps you generate a dispute letter. Your data never leaves your device.
Beta Notice: BillRx is currently in beta. The analysis may contain errors or miss issues on your bill. Always verify results independently before taking action.
Americans owe over $220 billion in medical debt, and a significant portion is due to billing mistakes that go unchallenged.
- $31.7B in Medicare improper payments in a single year (CMS CERT Program, FY 2024)
- 45% of insured adults received a bill for something they thought insurance should cover (Commonwealth Fund, 2024)
- 66.5% of personal bankruptcies cite medical bills or illness-related income loss (American Journal of Public Health, 2019)
- 74% of people who dispute a billing error get it corrected (JAMA Health Forum / USC Schaeffer, 2024)
Most people never challenge their bills. BillRx uses on-device AI to help you find errors so you can take action. Nothing is transmitted, stored, or logged. It's free, no accounts, no subscriptions.
- PDF parsing - Extracts line items from medical bill PDFs client-side using pdf.js
- Deterministic analysis - Catches math mismatches (qty x unit != total), duplicate/near-duplicate charges, suspicious generic fees, and totals reconciliation errors
- AI-powered analysis - A fine-tuned Qwen2.5-0.5B model runs locally via WebAssembly to explain each issue, rate severity, suggest questions to ask your provider, and provide corrected arithmetic
- Dispute letter generator - Fill in optional details (name, provider, account number) and download a personalized dispute letter PDF or copy an email draft to your clipboard
- Export report - Download a full PDF report of all flagged issues with AI explanations
- 100% private - Zero network requests for your data. Everything runs in the browser tab.
| Layer | Technology |
|---|---|
| Framework | Next.js 14 + TypeScript |
| Styling | Tailwind CSS |
| PDF parsing | pdfjs-dist (client-side) |
| PDF generation | jsPDF (client-side) |
| AI inference | @huggingface/transformers v3 + ONNX Runtime Web (WASM) |
| Model | Fine-tuned Qwen2.5-0.5B-Instruct (q4f16, ~350MB) |
| Testing | Vitest |
- Node.js 18+
- Any modern browser with WebAssembly support (all major browsers)
git clone https://github.com/Grey-Line-Interactive/BillRx.git
cd BillRx
npm install
npm run devOpen http://localhost:3000.
The AI model is a fine-tuned Qwen2.5-0.5B-Instruct quantized to ONNX q4f16 (~350MB). It is not included in this repo.
Fine-tuning details:
| Base model | Qwen/Qwen2.5-0.5B-Instruct |
| Method | QLoRA (4-bit NF4, LoRA rank 64, alpha 128) |
| Training data | 5,050 synthetic medical bill examples across 8 categories |
| Categories | Math errors, duplicates, generic fees, totals reconciliation, medical coding, patient rights, EOB interpretation, adversarial (not-an-error) |
| Output format | Structured sections: EXPLANATION, QUESTIONS TO ASK, CORRECTED ARITHMETIC, SEVERITY, NEXT STEPS |
| Export | Merged LoRA → ONNX via transformers.js convert script → q4f16 quantization |
Hosting: The model is served from Cloudflare R2 at models.billrx.io and downloaded to the browser automatically on first use. The training pipeline (training/) and fine-tuning guide (docs/model-fine-tuning-guide.md) are not included in this repo but are available on request.
Running without the model: The app still works without the model. Deterministic checks (math errors, duplicates, generic fees, totals) don't need it. Only the AI-powered explanations, severity ratings, and suggested questions require the model.
Local model setup: To run the AI model locally instead of fetching it from models.billrx.io, download the model files and place them in public/models/:
mkdir -p public/models/medbillcheck-qwen2.5-0.5b/onnx
# Download model files
curl -o public/models/medbillcheck-qwen2.5-0.5b/config.json \
https://models.billrx.io/medbillcheck-qwen2.5-0.5b/config.json
curl -o public/models/medbillcheck-qwen2.5-0.5b/tokenizer.json \
https://models.billrx.io/medbillcheck-qwen2.5-0.5b/tokenizer.json
curl -o public/models/medbillcheck-qwen2.5-0.5b/tokenizer_config.json \
https://models.billrx.io/medbillcheck-qwen2.5-0.5b/tokenizer_config.json
curl -o public/models/medbillcheck-qwen2.5-0.5b/generation_config.json \
https://models.billrx.io/medbillcheck-qwen2.5-0.5b/generation_config.json
curl -o public/models/medbillcheck-qwen2.5-0.5b/onnx/model_q4f16.onnx \
https://models.billrx.io/medbillcheck-qwen2.5-0.5b/onnx/model_q4f16.onnxThen update lib/llm/worker.ts to point to the local path:
// Change these lines:
const MODEL_HOST = 'https://models.billrx.io/'
// To:
env.allowLocalModels = true
env.allowRemoteModels = falseThe ONNX model file (model_q4f16.onnx) is ~350MB. The config and tokenizer files are small (a few KB each).
npm run dev # Start dev server
npm run build # Production build
npm run test # Run tests
npm run lint # Lintapp/
layout.tsx # Root layout, metadata, footer
page.tsx # Main page: upload flow, results, dispute builder
globals.css # Design system: gradients, animations, utilities
components/
DropZone.tsx # Drag-and-drop PDF upload
ModelLoader.tsx # AI model loading status + warm-up button
IssueList.tsx # Expandable issue cards with severity badges
ExportButton.tsx # PDF report export
DisputeBuilder.tsx # Dispute letter/email generator form
PrivacyBadge.tsx # "Runs locally" indicator
lib/
deterministic/
analyze.ts # Rule-based bill analysis (math, duplicates, fees, totals)
llm/
prompting.ts # Prompt assembly, response parsing, hallucination detection
useLLM.ts # React hook: model loading, inference via Web Worker
worker.ts # Web Worker for LLM inference (keeps UI responsive)
pdf/
parse.ts # Client-side PDF text extraction via pdfjs-dist
billDetails.ts # Regex-based bill detail extraction (names, dates, accounts)
candidates.ts # Issue candidate generation (static + checklist patterns)
dispute.ts # Dispute letter and email text generation
tests/
prompting.test.ts # Tests for prompt assembly and response parsing
- Upload - User drops a PDF.
pdfjs-distextracts text rows client-side. - Deterministic scan -
analyzePdf()runs rule-based checks: math mismatches, duplicate charges, suspicious generic fees, totals reconciliation. - AI analysis - Each flagged issue is sent to a fine-tuned Qwen2.5-0.5B model running locally via WebAssembly in a Web Worker. The model streams back structured analysis: explanation, severity, questions to ask, corrected math, and next steps.
- Results - Issues are displayed with expandable detail cards. Users can export a PDF report or generate a personalized dispute letter.
No data leaves the browser at any point in this pipeline.
BillRx uses WebAssembly for AI model inference, which is supported by all modern browsers. The deterministic checks (math errors, duplicates, generic fees) work in any browser. AI-powered explanations require enough memory to load the ~350MB model.
| Browser | Supported |
|---|---|
| Chrome / Edge | Yes |
| Firefox | Yes |
| Safari | Yes |
| Mobile browsers | Yes (performance varies by device) |
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
# Run tests before submitting a PR
npm run test
npm run buildMIT
Your medical bill data is processed entirely in your browser. No bill content, PDF files, or analysis results are ever uploaded, stored, or transmitted to any server.
This site is hosted on Cloudflare Pages. Like any web host, Cloudflare automatically logs standard HTTP request metadata (IP address, page URL, browser type, country) when you load the page. This is infrastructure-level logging that applies to virtually every website on the internet. None of this metadata includes your bill data. It only shows that you visited the site. We have disabled all optional analytics and tracking. No cookies are set, no analytics scripts are loaded, and no third-party trackers are present.
BillRx is an informational tool and is not a substitute for professional medical billing or legal advice. All analysis runs entirely in your browser using on-device AI. No medical data is uploaded, stored, or transmitted to any server.
Built by Grey Line Interactive
