Getting Started

Migrating from Vim OS JS

Open in Claude

Field renames and shape changes between the legacy Vim OS JavaScript SDK and the Vim App SDK

If you are porting an app from the legacy Vim OS JavaScript SDK (vim-os-js-browser), most of the work is mechanical. The hazard is that almost none of it fails loudly: a renamed path returns undefined rather than throwing, so a ported app compiles, runs, and quietly renders blanks.

This page lists the changes that behave that way. It is not a full capability comparison — it is the set of things that will cost you an afternoon of debugging if nobody tells you.

These do not throw

Every rename below reads as undefined on the old path. TypeScript will catch them if you type your entities against the SDK's exported types; it will not catch them if you kept your own interfaces from the old SDK.

Renames

EntityOld pathNew path
Patientcontact_infocontactInfo
Patientinsurance (single object)insurances[] (array)
Patientinsurance.ehrInsuranceinsurances[].payerName
DiagnosisonsetDateonSetDate — note the capital S
MedicationaddedDaterecordedDate
EncounterbasicInformation.encounterDateOfServicebasicInformation.dateOfService. A top-level dateOfService also exists but is deprecated on the collection — do not migrate onto it
Encounterassessment.diagnosisCodesassessment.diagnoses
Referralconditions.diagnosis[]conditions[] — the wrapper is gone

Shape changes

Medications flattened. The old Medication nested basicInformation and dosage; the new one is flat. basicInformation.medicationName → medicationName, dosage.strength.value → strength, and so on. The new type adds quantity, frequency, endDate and onSetDate.

Lab results and vitals restructured. Both moved from a basicInformation-shaped record to { basicInformation, results } and { basicInformation, values } respectively.

Patient lists are now fields too. problems, medications, allergies, labResults, vitals and insurances are present on the Patient entity as well as callable through sdk.ehr.api.patient.*. If the array you need is already in context, you may not need the call.

Providers flattened. The old Provider nested demographics and facility. The new one is flat — firstName, lastName, middleName, npi, ehrProviderId, specialty — and specialty is a single string rather than string[]. An embedded provider no longer carries facility; read it from the standalone ProviderRecord via sdk.ehr.api.provider.getById({ providerId }).

Referral reasons is singular. string[] became string. A referral that carried several reasons cannot round-trip.

Fields with no replacement

EntityFieldNote
Patientaddress.fullAddressCompose it from address1, address2, city, state, zipCode
Patientidentifiers.vimPatientIdNo Vim-namespaced patient key. identifiers.id exists but is deprecated on the collection in favour of identifiers.ehrPatientId, so migrate onto that
Encounterassessment.diagnosisCodesNotesThe new assessment is { diagnoses, generalNotes } — no per-diagnosis note
Referralidentifiers.vimReferralIdNo Vim-namespaced referral key
ReferralprocedureCodes.cpts[]A referral cannot carry procedure codes
OrderprocedureCodes[], loincCodes[], targetProviderSee EHR Connectivity for what an order does carry
ProviderproviderDegree, typeNo 'PROVIDER' | 'FACILITY' discriminator
ProceduresystemA procedure code arrives without its code set, so CPT and HCPCS are indistinguishable
—utils.copyToClipboard()There is no utils namespace; use the platform clipboard API

Present, but deprecated — don't migrate onto these

These fields still resolve, so nothing breaks if you use them, but the collection marks them deprecated and names a replacement. Migrating onto one means migrating twice.

EntityDeprecated fieldUse instead
Patientidentifiers.ididentifiers.ehrPatientId
Encounterididentifiers.ehrEncounterId
EncountertypebasicInformation.type
EncounterisSignedbasicInformation.status — 'LOCKED' / 'UNLOCKED'
Encounterdiagnosesassessment.diagnoses
EncounterdateOfServicebasicInformation.dateOfService

The SDK's generated types carry a @deprecated tag on every deprecated field, at any depth, with the same replacement text, so your editor flags each one where you use it. This table lists the ones you are most likely to meet.

Things that moved rather than disappeared

User and organization details. The old SDK put the provider's name, email, NPI and roles on vimOS.sessionContext.user. The new sdk.sessionContext carries userId, account, ehrType, sessionId and deviceId — identity of the session, not the person. For the person, exchange the ID token with your own backend and verify it server-side before trusting it — the session fields are unsigned page values, and the ID token is the only part a server can check. See Initialization and Authentication.

Writeback pre-flight. canUpdateEncounter() / canUpdateReferral() / canUpdateOrder() are replaced by getCapability('update') and hasPermission('update') — see Writeback. Two differences worth knowing: the new check is whole-entity by default rather than per-field, and disruptive writes are now gated behind requestPermission('update', { fields }), which the old SDK had no equivalent of and which is where you scope to specific paths.

Orders. The old SDK exposed ehrState.orders as an array of everything in context. Orders now arrive through the order_select and order_sign workflow events, and sdk.ehr.api.order.getOrderById().

On this page