For the complete documentation index, see llms.txt. This page is also available as Markdown.

Typical Project Setup

A Health Universe React app is an ordinary Node project — there's nothing special about the layout beyond installing the SDK and wiring a few build-time settings so it serves correctly behind a path prefix. The react-starter repo is a complete worked example; clone it as a starting point.

Step 1: Create a GitHub Repository

Push your app to a GitHub repository. As with the other runtimes, the repo must be reachable by Health Universe to deploy it.

Step 2: Repo layout

A typical Vite-based React app looks like:

my-clinical-app/
├── package.json          # dependencies + build/start scripts (drives runtime detection)
├── vite.config.js        # base path + optional dev proxy
├── index.html
└── src/
    ├── main.tsx          # mounts <HUProvider> + your app
    ├── HUProvider.tsx     # wraps HealthUniverseProvider (see "Your First App")
    └── …                  # your components, using the SDK hooks

package.json is the file the platform inspects to identify the runtime. A React (Vite) SPA only needs a build script — the platform serves the build output for you, so no start script is required:

{
  "name": "my-clinical-app",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "@health-universe/react": "^0.1.0",
    "@tanstack/react-query": "^5.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}

A Next.js or Node app instead needs a start script that listens on the port the platform provides (PORT, set to 8501) — e.g. "start": "next start -p $PORT".

Step 3: Build & run — static SPA vs Node server

How your app runs on Health Universe depends on the framework, and the platform picks the right mode automatically:

  • React (e.g. Vite) — built as a static SPA. Health Universe runs your build step, then serves the static output (dist/ or build/) with a single-page-app fallback. There is no long-running server process, and a start script, if present, is ignored.

  • Next.js / Node — run as a Node server. After the build, Health Universe runs npm run start, so your package.json must expose a start script that listens on PORT (8501). Next.js apps also need basePath configured (see Step 5).

Step 4: Runtime auto-detection

When you deploy, Health Universe inspects your repository and auto-detects the runtime from package.json (the deploy "main file" is package.json; in a monorepo it's <your-app-folder>/package.json). You don't choose React/Next.js/Node from a dropdown — the dependencies decide:

  • a next dependency → Next.js (Node server),

  • otherwise a react / react-dom dependency → React (static SPA),

  • otherwise → a plain Node server.

This determines whether the app is served as static assets or run as a Node server.

Step 5: Base-path handling

Deployed apps are served under a path prefix, e.g. https://apps.healthuniverse.com/<slug>/, not a dedicated subdomain. For assets and client-side routing to resolve correctly, your build must know that prefix.

The platform injects the prefix at build time under several names so each framework can read it — VITE_BASE_PATH (Vite), NEXT_PUBLIC_BASE_PATH (Next.js basePath), PUBLIC_URL (CRA), and a bare HU_BASE_PATH. Wire the right one into your build. For Vite:

Client-side routing: strip the trailing slash

If you use a client-side router (React Router, etc.), point its basename at the same prefix — but strip the trailing slash first. Vite's base keeps the trailing slash (/<slug>/) because that's correct for asset URLs, but React Router treats a basename of /<slug>/ as not matching the no-trailing-slash landing URL /<slug> — so the app mounts to a blank page even though every asset loaded fine. Strip it so /<slug>, /<slug>/, and /<slug>/... all match:

This is the most common blank-page-after-deploy cause once you add routing: assets resolve (correct base), but no route matches the landing URL. Don't use import.meta.env.BASE_URL for the basename directly — it carries the same trailing slash. Any in-app URLs you build by hand should still use the un-stripped BASE_URL so asset paths stay correct.

When deployed, Health Universe also injects the API origin and account settings (e.g. VITE_HU_API_URL, VITE_CLERK_PUBLISHABLE_KEY) at build time, so the SDK is configured for you and the signed-in user is already authenticated — no secrets to manage in your repo for the default deployed setup.

Step 6: Local development against a remote API

To develop against a remote API (staging or a preview) without running a local backend — and without CORS headaches — proxy /api through your dev server and point the SDK at the same origin. With Vite:

Then set VITE_HU_API_URL= (empty → same-origin) and VITE_HU_API_PROXY=https://<staging-host>, and sign in with the matching Clerk development instance (pk_test_…).

If you reinstall the SDK and an import looks stale (does not provide an export named …), clear the Vite optimize cache (rm -rf node_modules/.vite) and restart the dev server.

Step 7: Commit and deploy

Commit your code, push to GitHub, then deploy via Create → Source Code. See Deploying to Health Universe for the step-by-step deploy flow.

Last updated

Was this helpful?