Tutorials
Learn how to build healthcare applications with Medict through step-by-step tutorials.
Quick Start Tutorial
Get up and running with Medict in 5 minutes.
Prerequisites
- Node.js 18+ installed
- A Medict account (free tier available)
- Basic knowledge of JavaScript/TypeScript
Step 1: Install Medict SDK
npm install @medplum/core @medplum/react
Step 2: Initialize the Client
import { MedictClient } from '@medplum/core';
const client = new MedictClient({
baseUrl: 'https://api.medplum.com',
clientId: 'your-client-id',
onUnauthenticated: () => {
// Handle authentication
}
});
Step 3: Create Your First Patient
const patient = await client.createResource({
resourceType: 'Patient',
name: [{
use: 'official',
family: 'Doe',
given: ['Jane']
}],
gender: 'female',
birthDate: '1990-01-01'
});
console.log('Created patient:', patient.id);
Building a Patient Portal
Learn how to create a complete patient portal application.
Project Setup
-
Create a new React application:
npx create-react-app patient-portal --template typescript cd patient-portal npm install @medplum/core @medplum/react -
Set up authentication:
import { MedictClient } from '@medplum/core'; import { MedictProvider } from '@medplum/react'; const client = new MedictClient({ baseUrl: 'https://api.medplum.com', clientId: 'your-client-id' }); function App() { return ( <MedictProvider medplum={client}> <PatientPortal /> </MedictProvider> ); }
Patient Dashboard
Create a dashboard showing patient information:
import { useResource } from '@medplum/react';
function PatientDashboard({ patientId }) {
const patient = useResource('Patient', patientId);
if (!patient) {
return <div>Loading...</div>;
}
return (
<div className="patient-dashboard">
<h1>Welcome, {patient.name?.[0]?.given?.[0]}</h1>
<div className="patient-info">
<p>Date of Birth: {patient.birthDate}</p>
<p>Gender: {patient.gender}</p>
</div>
</div>
);
}
Viewing Appointments
import { useSearchResources } from '@medplum/react';
function AppointmentsList({ patientId }) {
const appointments = useSearchResources('Appointment', {
patient: `Patient/${patientId}`,
status: 'confirmed'
});
return (
<div className="appointments">
<h2>Upcoming Appointments</h2>
{appointments?.map(appointment => (
<div key={appointment.id} className="appointment-card">
<h3>{appointment.description}</h3>
<p>Date: {appointment.start}</p>
<p>Status: {appointment.status}</p>
</div>
))}
</div>
);
}
Building a Provider Dashboard
Create a dashboard for healthcare providers to manage patients.
Provider Authentication
import { useMedict } from '@medplum/react';
function ProviderLogin() {
const medplum = useMedict();
const handleLogin = async () => {
await medplum.signInWithRedirect({
clientId: 'your-client-id',
redirectUri: window.location.origin + '/dashboard'
});
};
return (
<button onClick={handleLogin}>
Sign in as Provider
</button>
);
}
Patient Search
function PatientSearch() {
const [searchTerm, setSearchTerm] = useState('');
const [patients, setPatients] = useState([]);
const medplum = useMedict();
const searchPatients = async (term) => {
if (term.length < 2) return;
const results = await medplum.searchResources('Patient', {
name: term
});
setPatients(results);
};
return (
<div className="patient-search">
<input
type="text"
placeholder="Search patients..."
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value);
searchPatients(e.target.value);
}}
/>
<div className="search-results">
{patients.map(patient => (
<div key={patient.id} className="patient-result">
<h3>{patient.name?.[0]?.given?.[0]} {patient.name?.[0]?.family}</h3>
<p>DOB: {patient.birthDate}</p>
<button onClick={() => viewPatient(patient.id)}>
View Details
</button>
</div>
))}
</div>
</div>
);
}
Working with Observations
Learn how to record and retrieve clinical observations.
Recording Vital Signs
async function recordVitalSigns(patientId, vitalSigns) {
const observation = await medplum.createResource({
resourceType: 'Observation',
status: 'final',
category: [{
coding: [{
system: 'http://terminology.hl7.org/CodeSystem/observation-category',
code: 'vital-signs'
}]
}],
code: {
coding: [{
system: 'http://loinc.org',
code: '85354-9',
display: 'Blood pressure panel'
}]
},
subject: {
reference: `Patient/${patientId}`
},
component: [
{
code: {
coding: [{
system: 'http://loinc.org',
code: '8480-6',
display: 'Systolic blood pressure'
}]
},
valueQuantity: {
value: vitalSigns.systolic,
unit: 'mmHg'
}
},
{
code: {
coding: [{
system: 'http://loinc.org',
code: '8462-4',
display: 'Diastolic blood pressure'
}]
},
valueQuantity: {
value: vitalSigns.diastolic,
unit: 'mmHg'
}
}
]
});
return observation;
}
Retrieving Patient Observations
function PatientObservations({ patientId }) {
const observations = useSearchResources('Observation', {
patient: `Patient/${patientId}`,
category: 'vital-signs'
});
return (
<div className="observations">
<h2>Vital Signs</h2>
{observations?.map(obs => (
<div key={obs.id} className="observation">
<h3>{obs.code?.text || 'Vital Signs'}</h3>
<p>Date: {obs.effectiveDateTime}</p>
{obs.component?.map(comp => (
<div key={comp.code?.coding?.[0]?.code}>
<strong>{comp.code?.text}:</strong> {comp.valueQuantity?.value} {comp.valueQuantity?.unit}
</div>
))}
</div>
))}
</div>
);
}
Next Steps
- Learn about FHIR Basics
- Explore Charting workflows
- Understand Authentication
- Build with React Components