← Back to Blog

FHIR Integration With EPIC: What I Wish I Knew Before Starting

February 22, 202610 min readPratik Awaik

I'm not going to pretend I've built dozens of healthcare apps. I haven't. But I recently completed a project for a client building a healthcare app for the US market, integrating with EPIC's FHIR API to pull patient data and generate STI risk assessments. The app processes patient observations - labs, test history, relevant vitals - and produces risk scores that help patients and their partners make more informed decisions about their sexual health.

Honestly? That single project taught me more about healthcare software than any tutorial could have. The challenges were real, the regulations were...let's say “comprehensive,” and the learning curve was basically a cliff.

So this isn't from someone claiming to be a healthcare IT veteran with 50 projects under their belt. This is from someone who just climbed that cliff, and I figured I'd share the view from up here.

System Architecture

Expo React NativeMobile app
NestJS APIAWS Lightsail
EPIC FHIR API
SupabaseDatabase & Auth

FHIR: Easier Than You Think, Until It Isn't

When I first heard about FHIR (Fast Healthcare Interoperability Resources), I thought, “Great, a standardized API. This should be straightforward.”

And it kind of is! FHIR uses REST APIs, returns JSON/XML, and if you're a developer, the concepts feel familiar. Making a basic API call to EPIC looks like any other API you've worked with:

GET https://fhir.epic.com/api/FHIR/R4/Observation/12345

Clean, simple, works as expected.

Then you try to actually use that data, and you discover that a single “Observation” resource (which includes lab results, vital signs, etc.) can have about 47 nested fields, each with its own quirks. Finding the actual test result value you need feels like a treasure hunt.

Here's what extracting a simple lab result from a FHIR Observation actually looks like:

// You'd expect: observation.value
// Reality:
const result = observation
  ?.resource
  ?.valueQuantity
  ?.value;

// But wait — some labs return valueCodeableConcept
// or valueString instead of valueQuantity.
// And the coding system might be LOINC, SNOMED,
// or something vendor-specific.

Oh, and different EHR vendors implement FHIR differently. EPIC does things one way, Cerner another way. The codes for the same lab test? Totally different. You end up writing a lot more conditional logic than you expected.

OAuth in Healthcare Is Like Regular OAuth's Overprotective Parent

I've implemented OAuth before for social logins. Healthcare OAuth follows similar principles but with, shall we say, more rules.

Healthcare uses “SMART on FHIR” for authorization, and the key difference is granular scopes. You don't just request “health data access.” You request very specific permissions like:

  • patient/Observation.read for labs and vitals
  • patient/Condition.read for diagnoses
  • patient/MedicationRequest.read for medications

My first instinct was to request broad scopes - “might as well grab everything now.” But the more I read about healthcare UX, the more I realized that's a mistake. Patients see those consent screens. If your app is asking for 15 different data types when it only needs lab results, that's a trust problem.

We kept our scopes as narrow as possible - only requesting what the app actually needed for STI risk assessment. It's a small thing, but in healthcare, respecting data minimization matters.

HIPAA: What I Learned (And Why Budget Matters)

Before this project, I understood HIPAA conceptually. Encrypt things, control access, keep logs. Simple enough, right?

Then I learned that HIPAA has two distinct sides: technical safeguards and organizational compliance. The technical side - encryption, access controls, audit logging - lives in the code. The organizational side - signing Business Associate Agreements, workforce training, formal risk assessments, breach response plans - requires dedicated budget, legal counsel, and compliance consultants.

I'll be honest: for this project, we didn't achieve full HIPAA compliance. The client's budget didn't allow for HIPAA-eligible cloud service tiers, signed BAAs with every vendor, or formal third-party compliance audits. These things are expensive, and not every project can afford them in the first release.

But here's what we did do - we built with HIPAA in mind from day one:

  • Encryption in transit and at rest. TLS for all API communication, encrypted database via Supabase, enforced SSL connections. The data protection layer is there.
  • Row-level security via Supabase. Database-level policies that control which users can access which rows. It's not full role-based access control yet, but it's a solid foundation.
  • Secure authentication. Supabase Auth with SMART on FHIR for EPIC data access. Separate auth flows for different concerns.

What would it take to get to full HIPAA compliance from here? Adding comprehensive audit logging, implementing role-based access controls, migrating from Lightsail to EC2 (which is HIPAA-eligible), signing BAAs with all vendors handling PHI (Supabase and AWS both offer BAA options on their higher tiers), conducting a formal risk assessment, and bringing in a compliance consultant. The foundation is there - it's a matter of budget and organizational commitment.

Key takeaway: HIPAA compliance isn't just a developer problem. It's a combination of technical safeguards, organizational processes, and budget. As a developer, the best thing you can do is build a HIPAA-ready architecture from the start - so that when the client is ready to go fully compliant, it's an upgrade, not a rewrite.

The Sandbox Will Fool You

EPIC provides a sandbox with synthetic patient data for development. It's clean, well-formatted, and complete. Every field is where you'd expect it to be. Building against it feels straightforward.

But everything I've read and heard from developers working with production EHR data paints a very different picture:

  • Missing fields you assumed would always be there
  • The same diagnosis coded three different ways
  • Values in unexpected formats
  • Duplicate entries with slight variations

We built against the sandbox, and it worked great. But I'd be naive to think production data will be that clean. It's something I'd prioritize much earlier next time - writing defensive parsing logic that treats every FHIR field as potentially missing or malformed.

Healthcare Workflows Don't Map Neatly to Code

As a developer, I think in terms of user flows and data models. Healthcare involves regulations, liability concerns, and clinical practices that don't always translate directly to “if this, then that.”

Looking back, here are questions I wish we'd thought about earlier:

  • What if the app calculates a high-risk score? What's the liability if someone doesn't act on it?
  • What if the data from EPIC is incorrect? (It happens.) Who's responsible?
  • What about patients under 18? Sexual health data has extra privacy protections.
  • If you want to use anonymized data to improve algorithms, you need explicit consent. That's a whole separate flow.

These are the kinds of questions that don't show up in tutorials. We worked through what we could with the client, but in hindsight, consulting a healthcare attorney early would have been worth the investment.

Tech Stack Choices That Worked

For this project, I used:

  • Frontend: Expo React Native - let us target both iOS and Android from one codebase, which kept costs down for a project that needed to ship fast. Expo's managed workflow also simplified builds and OTA updates.
  • Backend: NestJS, deployed on AWS Lightsail - NestJS's modular architecture helped keep the FHIR integration code organized, especially when handling multiple resource types (Observations, Conditions, DiagnosticReports) in parallel. Lightsail kept infrastructure simple and predictable cost-wise. For full HIPAA compliance, we're planning to migrate to EC2.
  • Database & Auth: Supabase - PostgreSQL under the hood with built-in auth, row-level security, and enforced SSL connections. Supabase gave us a production-ready database and authentication layer without having to build either from scratch.
  • FHIR Auth: SMART on FHIR authorization with granular scopes for accessing patient data from EPIC.

TypeScript was a great call for this project - healthcare data structures are complex, and type safety caught several bugs early. If I started over, I'd invest more time upfront in building proper FHIR data validation and error handling. When you're parsing deeply nested resources from different vendors, edge cases show up fast.

What I'd Tell Past Me

If I could go back to the beginning of this project, here's what I'd say:

  1. 1.Budget more time for testing. Healthcare data is messy. You'll find edge cases you didn't anticipate. Plan for it.
  2. 2.Understand the domain deeply. Read the regulations, study the data models, and talk to your client extensively. We didn't have direct access to healthcare providers, and there were moments where that input would have saved us time.
  3. 3.Start with a narrow scope. Don't try to build everything at once. Pick one specific problem and solve it well.
  4. 4.Take HIPAA seriously from day one. You can't bolt it on later. Build with compliance in mind from the start.
  5. 5.Patient consent isn't just legal compliance; it's trust building. Be transparent about what data you're using and why. Give users control.

Final Thoughts

This project gave me real appreciation for why healthcare software is complex. The data is inconsistent, the regulations are strict (for good reasons), the stakes are high, and the workflows don't always fit neatly into code. But it's also rewarding in a way most software projects aren't.

I've successfully integrated with EPIC's FHIR API and built security-first architecture with HIPAA in mind. I have a much clearer picture now of what full compliance involves. Now I'm looking to apply these lessons to help healthcare providers build software they actually need - patient portals, telemedicine platforms, and practice management tools that integrate with existing systems.

The learning curve was steep, but worth it.

Resources That Helped

If you're building a healthcare app, these were useful:

  • EPIC FHIR Documentation: fhir.epic.com (excellent sandbox)
  • HL7 FHIR Specification: hl7.org/fhir (the official standard)
  • SMART Health IT: smarthealthit.org (great SMART on FHIR resources)
  • HIPAA Journal: hipaajournal.com (practical compliance guidance)

Building Healthcare Software?

I help healthcare providers and health-tech startups build secure, HIPAA-ready healthcare software - from FHIR integrations to patient portals to telehealth platforms.

If you're starting a healthcare project and want to avoid the mistakes I made, let's chat - I offer a free 30-minute introductory call.

Book a Free Call