The first SMART on FHIR app I helped wire into a live workflow looked perfect in dev. It launched, pulled the patient, rendered the right chart slices, and wrote the note draft back into the expected place. Then we put it in front of real users and it fell apart for a reason nobody likes to admit: it was technically correct and operationally wrong.
The app opened in the middle of a chart review sequence when the clinician was expecting a medication reconciliation view. The auth token was fine. The FHIR queries were fine. The workflow was not. That is the mistake teams make over and over. They treat SMART on FHIR as an integration problem when it is actually a choreography problem.
I work in FHIR Architecture, and I have lost more time to launch-context bugs than to payload shape bugs. That surprises engineers who are new to healthcare. They expect the spec to be the hard part. It is not. The hidden work is around app state, user identity, chart selection, and what happens when the EHR sends you a patient in one moment and the user opens a different chart in the next.
SMART on FHIR looks simple on paper because the spec gives you a clean mental model: secure launch, retrieve context, call FHIR endpoints, render UI. In practice, every EHR adds implementation texture. Epic, Oracle Health, and other platforms all respect the standard differently at the edges. If you do not design for those edge behaviors from day one, you end up with an app that only works in a happy-path sandbox.
Here is the part I wish more teams understood before they start coding.
You are not building a standalone web app. You are building a guest inside another system. That means your app inherits constraints you do not control: launch timing, session termination, browser policies, chart navigation, and sometimes the user’s expectation that the app should behave as if it were native to the EHR. It never is. The better your app respects those constraints, the less friction it creates.
When AST builds these integrations, I start with launch behavior before I touch the UI layer. That ordering matters. Most teams start by sketching screens. I start by writing down the launch contract, then the failure states, then the FHIR reads, then the user journeys. It is boring. It is also the difference between a pilot that survives live use and a pilot that becomes a ticket magnet.
What I pin down before writing a single endpoint
The launch contract is the real foundation. I want these questions answered in writing before implementation begins:
- Is the app launched from a patient chart, a practitioner workspace, an encounter, or a generic EHR shell?
- Which context parameters are guaranteed by the host system and which are optional?
- What is the expected session lifetime, and who owns re-authentication?
- Does the app need read-only behavior, or does it also write back notes, tasks, orders, or communications?
- What is the fallback when context is missing or stale?
I know that sounds like project management. It is not. It is architecture. If you do not define these edges, your app will end up duplicating chart context in its own database, and that is how healthcare teams create drift between the EHR and the thing that sits on top of it.
For production builds, I prefer a narrow start. One user role. One launch point. One chart type. One primary action. That constraint is not weakness. It is how you learn whether the app can survive the real clinic. AST has seen this repeatedly in integration work: the app that tries to do everything on day one usually ends up doing nothing reliably.
| Decision | What I recommend | Why it matters |
|---|---|---|
| Launch from chart context | Require explicit context validation | Stops silent misrouting to the wrong patient |
| Token handling | Keep app state separate from auth state | Refreshes should not destroy the workflow |
| Data access | Read only the FHIR resources you need | Smaller surface, faster load, fewer permission failures |
| Write back | Use one clearly owned system of record | Avoids duplicate documentation and reconciliation pain |
That last row is the one teams get wrong. They add a write-back feature because it sounds helpful, then discover three months later that nobody wants notes written into a second place unless the destination is visibly trusted. If the app is generating content for a clinician, the write path has to be obvious, predictable, and recoverable. No mystery saves. No hidden submission flows.
AST’s implementation pattern for SMART on FHIR
This is the sequence I use when I want an app to survive beyond a demo:
- Lock the launch contract Document every context parameter, every host expectation, and every failure mode before the UI is designed.
- Build a tiny auth shell Get OAuth, token refresh, and session teardown working in the host browser before adding app logic.
- Resolve context first Confirm the current user, patient, encounter, and chart state before any screen renders clinical content.
- Read the minimum FHIR set Fetch only the resources required for the current task, then cache just enough to keep the interface responsive.
- Design recovery states Handle refresh, tab reopen, expired sessions, missing scope, and stale chart context explicitly.
- Test inside the host EHR Run the app where clinicians use it, not just in a local browser with ideal conditions.
That sequence sounds rigid because it is. Clinical workflow integration rewards discipline. If you skip step two and build a beautiful interface first, you will pay for it when the token expires and the app can no longer explain to the user what happened. If you skip step five, your support queue will fill with complaints that are really state-management bugs.
At AST, I have seen teams waste weeks because they assumed the browser was neutral. It is not. The browser inside an EHR session is part of the product surface. That means popup behavior, embedded frames, cross-window communication, and cookie policy are not incidental details. They are your runtime.
One more thing I tell every engineering team: do not over-read the chart. The FHIR server may expose dozens of resources, but your app should not vacuum them up because they are available. That almost always creates latency, complicates permissions, and confuses the clinician with too much context. Good workflow apps feel small for a reason. They are focused.
What usually breaks first
If you are building a SMART on FHIR app for clinic use, expect these failure modes first:
- Wrong-screen launch The app opens correctly but not at the point in the workflow the user expected.
- Context drift The patient or encounter changes underneath the app and the UI does not notice.
- Scope mismatch The app asks for a permission path the EHR admin does not want to approve.
- Refresh amnesia Reloading the page destroys task state, forcing the user to start over.
- Write-back ambiguity The app can produce content, but nobody agrees where it belongs.
- Sandbox-only confidence The app passes dev testing and then fails on browser behavior, host policy, or patient context in production.
The irony is that none of these are exotic. They are routine. But they appear only after the app is installed into a real clinic routine, which is why teams underestimate them. I do not trust a SMART app until I have seen it survive a user switching charts, a token refresh, and a full page reload without losing the task.
If you are evaluating a vendor or building in-house, treat the banner as a diagnostic signal, not just a UX flourish. I have used that exact pattern in AST delivery work to catch launch mismatches that would have otherwise been blamed on the EHR.
How I test SMART on FHIR integrations before go-live
My test plan is more like a clinic script than a software checklist. I want to see the app behave under the same pressures clinicians create accidentally all day long:
- Launch from the host system Open the app from a real chart context, not a bookmarked URL.
- Switch patients Verify the app detects the context change and does not display stale data.
- Expire the session Confirm the app explains re-authentication without losing task state.
- Close and reopen Make sure the app can recover after an accidental tab close or refresh.
- Remove a scope See how the app behaves when permissions are narrower than expected.
- Run with slow FHIR responses Validate loading states, retries, and timeouts under realistic network delay.
That last test matters more than people think. Fast internal servers can hide brittle UI assumptions. Then the app goes into a hospital network with slower paths to the FHIR server and suddenly the interface feels broken. It is usually not broken. It is unprepared.
If you are comparing build approaches, I would make the comparison blunt. A SMART on FHIR app is not the same thing as an iframe page, a sidecar browser tool, or a generic web portal module. The launch and auth rules are different, the trust model is different, and the operational support burden is different. That is why I tell teams to choose the integration shape before choosing the component library.
Where AST fits when the app has to live in a real workflow
AST builds these systems as integrated clinical engineering work, not isolated code drops. That matters because the app does not exist on its own. It sits in a workflow with clinicians, admins, security reviewers, and the EHR team all touching it at different layers. In our delivery work, the technical problem is usually straightforward. The coordination problem is the real one.
We see the same pattern across EMR integrations and clinical workflow tools: the host system already has users, roles, and chart state. Our job is to join that world without duplicating it. That is why I like clean launch contracts and minimal resource reads. It keeps the app honest. It also makes support easier when the inevitable edge case appears.
If you are building this yourself, or buying a platform that claims to support SMART on FHIR, ask how it handles the ugly parts. Not just auth. Not just FHIR validation. Ask about launch mismatch, stale context, session recovery, write-back ownership, and host-browser behavior. Those are the questions that separate demo-grade software from software clinicians actually keep open.
The biggest lesson I can give you is simple: stop treating SMART on FHIR like a badge of interoperability. It is a workflow contract. If you honor the contract, the app becomes part of the clinician’s day. If you ignore it, the app becomes one more tab nobody wants to open.
Build a SMART on FHIR app that survives the clinic
If you need help turning launch context, auth, and FHIR reads into a workflow clinicians will actually use, I can help you design the integration the right way from the start. AST builds these systems inside real delivery constraints, not lab conditions.





Comments
Comments are warming up. Live, no-sign-in discussion will appear here shortly.
Have a question now? Email info@allstartech.net.