Setup Guide

Get DH Field EMR running on your device in a few minutes — offline-only, or synced to your own free cloud.

⚡ Stuck? Get AI-guided help

Download the complete reference & troubleshooting PDF, then upload it to Claude (or any AI assistant) and describe your problem. It's written for an AI to read, so it can walk you through setup, fix Supabase / sync errors, and help you customize the app.

Download the Reference PDF

1. What you'll need

No app store, no purchase

DH Field EMR is a web app. You "install" it by adding it to your home screen — there's nothing to buy and no account to create with us.

2. Install the app

First, open the app in your browser:

Launch the App

Then add it to your home screen so it opens like a normal app and works offline:

iPad & iPhone (Safari)

  1. Open the link above in Safari (not Chrome — only Safari can install on iOS).
  2. Tap the Share button (the square with an up-arrow).
  3. Choose Add to Home Screen, then Add.
  4. From now on, always open the app from the new home-screen icon — that's what makes it work reliably offline.

Android (Chrome)

  1. Open the link in Chrome.
  2. Tap the menu (⋮) and choose Install app (or tap the "Install" banner if it appears).
  3. Open it from the new icon in your app drawer.

Laptop / Desktop (Chrome or Edge)

  1. Open the link in Chrome or Edge.
  2. Click the Install icon in the address bar (a small monitor with a down-arrow), or use the menu → Install.
Updating later

When a new version ships, the app shows a small "Update now" bar — just tap it. You can always check which version you're running: it's shown next to the title at the top (e.g. v2026-05-30 17:22).

3. Choose how you'll use it

The first time you open the app, a short setup wizard asks how you want to run it. There are three choices:

Standalone (Offline Only)

Best for trying it out, or a single device with no need to share data.

New Organization

Best for the first device of a team. You'll create your own Supabase database (next section), and this device becomes the admin.

Join Existing Setup

Best for additional devices joining a team that's already set up. You'll paste the same Supabase URL and key your team already uses (see section 6).

Just want to look around?

Pick Standalone. It takes 10 seconds and you can explore everything. Nothing you enter is sent anywhere.

4. Set up your own cloud (Supabase)

This is the one technical step, and you only do it once for your whole team. It gives your records a safe home in the cloud that you own and control.

  1. Go to supabase.com and create a free account.
  2. Click New project. Give it a name (e.g. "Hope Clinic EMR"), set a database password (save it somewhere safe), pick a region near where you work, and create it. Wait a minute for it to finish setting up.
  3. In the left sidebar, open the SQL Editor and click New query.
  4. Copy the entire block below, paste it into the editor, and click Run. You should see "Success."
-- DH Field EMR — Supabase setup (run once). Safe to re-run.
CREATE TABLE IF NOT EXISTS records (
  id UUID PRIMARY KEY,
  device_id TEXT, site TEXT, date TEXT, mrn TEXT,
  given_name TEXT, family_name TEXT, name TEXT, sex TEXT, dob TEXT, phone TEXT,
  pregnant TEXT, breastfeeding TEXT, temp TEXT, bp TEXT, weight TEXT,
  allergies TEXT, current_meds TEXT, pmh TEXT, chief_concern TEXT,
  labs JSONB DEFAULT '{}'::jsonb, lab_comments TEXT,
  urinalysis JSONB DEFAULT '{}'::jsonb, blood_glucose TEXT,
  diagnosis TEXT, diagnosis_codes JSONB DEFAULT '[]'::jsonb,
  medications JSONB DEFAULT '[]'::jsonb, treatment_notes TEXT, treatment TEXT,
  procedures JSONB DEFAULT '[]'::jsonb, transport TEXT, travel_time TEXT,
  access_to_care JSONB, referral_type TEXT, referral_date TEXT, referral_status TEXT,
  imaging JSONB, surgery JSONB, provider TEXT, notes TEXT,
  custom_fields JSONB DEFAULT '{}'::jsonb, template_id TEXT, template_name TEXT,
  age_estimated BOOLEAN DEFAULT false, saved_at TIMESTAMPTZ,
  sync_version INTEGER DEFAULT 1, deleted BOOLEAN DEFAULT false,
  synced_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS devices (
  id TEXT PRIMARY KEY, name TEXT NOT NULL, role TEXT DEFAULT 'standard',
  org_name TEXT, last_sync_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS config (
  key TEXT PRIMARY KEY, value JSONB, updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_records_synced_at ON records (synced_at);
CREATE INDEX IF NOT EXISTS idx_records_device_id ON records (device_id);
CREATE INDEX IF NOT EXISTS idx_records_mrn ON records (mrn);
ALTER TABLE records ENABLE ROW LEVEL SECURITY;
ALTER TABLE devices ENABLE ROW LEVEL SECURITY;
ALTER TABLE config  ENABLE ROW LEVEL SECURITY;
CREATE POLICY "anon_read_records"   ON records FOR SELECT USING (true);
CREATE POLICY "anon_insert_records" ON records FOR INSERT WITH CHECK (
  device_id IS NOT NULL AND EXISTS (SELECT 1 FROM devices WHERE id = device_id));
CREATE POLICY "anon_update_records" ON records FOR UPDATE USING (
  device_id IS NOT NULL AND EXISTS (SELECT 1 FROM devices WHERE id = device_id));
CREATE POLICY "anon_read_devices"   ON devices FOR SELECT USING (true);
CREATE POLICY "anon_insert_devices" ON devices FOR INSERT WITH CHECK (true);
CREATE POLICY "anon_update_devices" ON devices FOR UPDATE USING (true);
CREATE POLICY "anon_read_config"   ON config FOR SELECT USING (true);
CREATE POLICY "anon_write_config"  ON config FOR INSERT WITH CHECK (true);
CREATE POLICY "anon_update_config" ON config FOR UPDATE USING (true);
CREATE POLICY "no_delete_records" ON records FOR DELETE USING (false);
CREATE POLICY "no_delete_devices" ON devices FOR DELETE USING (false);
CREATE POLICY "no_delete_config"  ON config  FOR DELETE USING (false);

5. Connect the app

Back in the setup wizard (on the device you chose New Organization), you'll be asked for two things from Supabase:

  1. In Supabase, open Settings → API (the gear icon).
  2. Copy your Project URL — it looks like https://abcdxyz.supabase.co.
  3. Copy your anon key (also called the "publishable" key) — a long string starting with eyJ…. If you only see "Publishable" and "Secret," use Publishable. If your project shows newer keys, look for "Legacy anon / service_role keys" and copy the anon one.
  4. Paste both into the app's Supabase URL and Supabase Anon Key fields and continue.
  5. Let it seed the default presets (medications, diagnoses, sites, etc.), name this device, and set an admin password (this protects customization and settings).
Use the anon / publishable key — not the secret one

Never put your service_role or secret key in the app or share it. The anon/publishable key is the one meant for apps.

6. Add more devices

For every other phone, tablet, or laptop on your team:

  1. Install the app (section 2) and open it.
  2. In the setup wizard, choose Join Existing Setup.
  3. Paste the same Supabase URL and anon key the first device used. (Keep them somewhere your team can find — they're the "key" to your shared data.)
  4. Name the device. It'll pull down your presets and history automatically.

7. Make it yours

On the admin device, open Options (and Admin) to tailor the app to your clinic:

Full details are in the Admin Guide. Changes sync to every device automatically.

8. Your first patient

  1. Tap + New Encounter.
  2. Enter the patient's name and date of birth — the MRN fills in automatically.
  3. Pick a site and provider, record the complaint, vitals, labs, diagnosis, and any meds or referrals.
  4. Tap Save & Close — or, on a busy clinic day, Save & Next to jump straight to a fresh form.

9. Keeping your data safe

Two simple habits keep your records protected:

A note on offline storage

On iPads in particular, the operating system can occasionally clear a web app's local storage. In day-to-day use your records persist fine, but cloud sync and daily backups are what make your data truly safe — please use them.

10. Next steps