Engineering Case Study
A SMART on FHIR Implementation, Validated on the Epic Sandbox
Peerbits built a complete SMART App Launch → OAuth 2.0 + PKCE → patient‑context → FHIR resource access → Observation write‑back flow, and validated every step against Epic's FHIR R4 sandbox.
7
FHIR RESOURCES
80%+
TEST COVERAGE
201
WRITE STATUS
SMART launch flow
VERIFIEDOAuth 2.0 + PKCE
COMPLETEObservation write-back
201 OKReusable FHIR SDK
BUILT2
SMART launch flows supported
7
FHIR resources tested
12
Read / write operations completed
3
OAuth flows validated
9
Production readiness areas covered
80%+
Automated test coverage
Transparency note: internal Peerbits engineering demonstration, built and tested against Epic's non‑production sandbox. Not a client deployment; no live patient data was used. Epic is referenced only to identify the sandbox platform — nothing here implies Epic endorsement or certification.
CATEGORY
Healthtech · Interoperability
STANDARD
FHIR R4 · SMART App Launch
ENVIRONMENT
Epic non‑production sandbox
STACK
React + TypeScript, Node.js + NestJS, Redis
TIMELINE
3 weeks · 2 sprints
Why This Was Needed
The interoperability problem SMART on FHIR solves
Healthcare applications live or die by how easily they can plug into an EHR. Before diving into implementation, it's worth being explicit about what problem this solves and why it matters to a technical buyer evaluating an EHR integration partner.
THE PROBLEM
Every EHR exposes patient data differently, and most healthcare applications need to launch from inside the EHR, act on behalf of a specific clinician and patient, and read or write clinical data without ever seeing raw credentials.
THE SOLUTION SHAPE
Standardizes how an app is launched from within or alongside an EHR.
Authorizes the app without exposing credentials to the browser.
Standardizes the data model so the same code works across EHR vendors.
Build once, connect to any SMART-compatible EHR with configuration, not a rewrite.
Solution Approach
Architecture
React SPA
Vite + TypeScript
BFF
Node.js + NestJS
SMART Launch
PKCE · scopes
Epic Auth Server
OAuth2 · OIDC
FHIR R4 APIs
Epic sandbox
Redis
cache · session
Credentials never reach client-side code — all auth proxied through the BFF
React SPA (Vite + TypeScript)
Handles only UI rendering and state; talks to the backend-for-frontend only, never to Epic directly.
Node.js + NestJS BFF
Proxies the SMART on FHIR auth flow, normalizes FHIR responses, adds caching and audit logging. Credentials never reach client-side code.
Redis
Caches FHIR responses (5-minute TTL) and holds session tokens server-side.
Epic FHIR R4 Sandbox
Epic FHIR R4 sandbox plus Epic OAuth authorization server as the external system.
Technical Implementation
SMART on FHIR Authentication
The launch sequence end-to-end — from app launch to the first authorized FHIR call.
Scopes used:
openid fhirUser launch/patient patient/Patient.read patient/Condition.read patient/Observation.read patient/Observation.write patient/MedicationRequest.read patient/AllergyIntolerance.read patient/Encounter.read
- Discover authorization config via Epic's .well-known/smart-configuration endpoint.
- Generate a PKCE code verifier and derive the code challenge (BASE64URL-SHA256), stored server-side.
- Redirect the browser to Epic with the requested scopes and challenge.
- User authenticates and selects patient context on Epic's login screen; Epic redirects back with an authorization code and state.
- Backend validates state (CSRF protection) and exchanges the code for tokens server-side — never in the browser.
- Token response includes the access token and patient/launch context.
- 01
STEP 1
Launch App
Discover authorization config via Epic .well-known/smart-configuration endpoint.
- 02
STEP 2
PKCE Challenge
Generate code verifier and derive the code challenge (BASE64URL-SHA256), stored server-side.
- 03
STEP 3
Authorization Request
Redirect the browser to Epic with the requested scopes and challenge.
- 04
STEP 4
User Authentication
User authenticates and selects patient context on Epic login screen; Epic redirects back with an authorization code and state.
- 05
STEP 5
Token Exchange
Backend validates state (CSRF protection) and exchanges the code for tokens server-side — never in the browser.
- 06
STEP 6
FHIR API Calls
Backend calls permitted FHIR endpoints; proactively refreshes before expiry and clears sessions on logout.
Coverage
FHIR Resources
Read, write, and search coverage across the FHIR resources exercised in the sandbox.
| Resource | Read | Write | Search | Status |
|---|---|---|---|---|
| Patient | ✔ | – | ✔ | Verified complete |
| Condition | ✔ | – | ✔ | Verified complete |
| Observation | ✔ | ✔ | ✔ | Verified complete |
| MedicationRequest | ✔ | – | ✔ | Verified complete |
| AllergyIntolerance | ✔ | – | ✔ | Verified complete |
| Encounter | ✔ | – | ✔ | Verified complete |
| DocumentReference | ✔ | – | ✔ | Verified complete |
Deepest Implementation
Observation Write-Back
One of the strongest parts of this build: writing a structured clinical Observation back to Epic, not just reading data out.
- Observation submitted as write-scoped FHIR — not export via file, not manual entry.
- BFF builds a FHIR-compliant Observation payload (LOINC code, status, patient reference, effective date) from the sandbox.
- Submitted via the Epic sandbox — confirmed returning, matching a 201 Created response from the sandbox.
OBSERVATION · EXAMPLE
LOINC CODE
8867-4 (Heart rate)
STATUS
final
VALUE
76
UNIT
beats/min
EFFECTIVE DATE
2026-07-14T09:12:00Z
Validation Process
Reusable SDK & Testing
Every claim in this case study was validated, not assumed.
Validated with
SMART Launch — run end-to-end against the live sandbox launch URL.
FHIR APIs — every resource call executed against Epic FHIR R4 sandbox, not mocked.
Postman — a maintained collection covering auth, read, and write requests.
Capability testing — checked resource support against Epic CapabilityStatement.
Resource validation — responses checked against the FHIR R4 schema.
Reusable SDK
Reusable FHIR client package — one framework-agnostic, raw typed client per resource, reusable across FHIR-based projects.
Unit tests (Vitest) — ≥ 80% line coverage on the BFF and SDK.
Integration tests (Supertest) — full launch-to-write flow tested against the sandbox in CI.
E2E tests (Playwright) — five journeys through the patient-facing UI, sandbox-authenticated.
Performance baseline — recorded response times under sandbox rate limits.
What We Learned
Engineering Lessons
The specific, sometimes unglamorous things that made this implementation real rather than a demo.
Launch context handling
The patient and encounter context returned at token exchange has to be persisted and re-used consistently, or later FHIR calls silently return the wrong patient data.
Scope limitations
Epic enforces requested scopes strictly; a resource left out of the initial scope request fails at call time, not at launch, so scope planning has to happen up front.
Sandbox data inconsistencies
Synthetic sandbox patients don't always have data for every resource type, which looks like a bug until you cross-check against the sandbox patient roster.
Token expiration handling
Access tokens expire mid-session; refreshing proactively (rather than on 401) avoided dropped requests during longer clinical workflows.
FHIR resource availability differences
Not every resource is populated or writable in the sandbox the same way it would be in production, so capability statements need to be checked per environment, not assumed from documentation.
Security & Operational Controls
Built the way SMART implementations are expected to be built
PKCE
Code verifier/challenge prevents authorization-code interception.
State Validation
CSRF protection on every redirect back from Epic.
Secure Token Storage
Tokens held server-side only; never exposed to the browser.
HTTPS
TLS enforced end-to-end, including sandbox calls.
Least Privilege Scopes
Only the scopes required by the demo were requested.
Audit Logging
Every FHIR read/write logged with actor, resource, and timestamp.
Engineering Outcomes
Outcomes
SMART Launch
Successfully completed against Epic sandbox, end to end.
OAuth 2.0 + PKCE
Workflow validated, including token refresh and session teardown.
Observation Write-back
Completed and confirmed via a 201 Created sandbox response.
Reusable Components
FHIR client SDK, BFF auth module, and test harness ready for reuse.
End-to-end Interoperability
Demonstrated across read, write, and search on seven FHIR resources.
What Would Change for Production
From sandbox to production
A sandbox demo proves engineering capability — it is not a production deployment. Here is exactly what changes when this moves into a live EHR integration.
EHR App Registration
Formal app registration with the target EHR vendor, replacing the sandbox client ID.
Vendor Approval
Epic (or equivalent) certification/approval process before production access.
Production Credentials
Client secrets and signing keys managed through a secrets manager, not config files.
Patient Consent
Explicit consent capture and management, tied to the data actually being accessed.
Monitoring
Uptime, latency, and error-rate monitoring on every FHIR call.
Rate Limiting
Respecting and gracefully handling the EHR vendor production rate limits.
Retry Handling
Exponential backoff and idempotent retries for transient FHIR failures.
Multi-tenant & Audit Logging
Tenant isolation and audit-grade logging suitable for a compliance review.
Beyond This Project
A reusable interoperability accelerator
The FHIR client, the SMART auth module, and the test harness were built to be adapted to other SMART-compatible EHR platforms — not rewritten for each one.
This implementation was validated using the Epic SMART on FHIR sandbox environment. The architecture and reusable integration components are designed to accelerate production integrations with SMART on FHIR-compliant EHR platforms, subject to each vendor onboarding and certification process.
Tech Stack Used
Built with
Frontend
React 18 + TypeScript
BFF / API layer
NestJS + Node.js 20
Cache + session
Redis
Interop standard
FHIR R4 + SMART on FHIR
Authorization
OAuth 2.0 + PKCE
EHR
Epic FHIR R4 Sandbox
Unit / integration
Vitest + Supertest
E2E tests
Playwright
CI pipeline
GitHub Actions
Planning an Epic or FHIR Integration?
Talk to the engineers who built and validated this SMART on FHIR flow, sandbox to production checklist included.
Discuss Your Epic or FHIR IntegrationHealthcare Projects That Solve Real Technology Problems
Peerbits develops custom healthcare software solutions around your users, integrations, processes, data requirements, and long-term business goals.








