-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
This page takes you from a fresh clone to a running staff application with demo data, using only commands that work today. It is for a developer setting up for the first time.
| Tool | Version | Notes |
|---|---|---|
| Node.js | 22 | Pinned in .nvmrc. engine-strict=true in .npmrc means a different major fails the install rather than warning. |
| pnpm | 10.30.1 | Pinned in the root package.json packageManager field. Install it through corepack, not globally. |
| PostgreSQL | 17 | Only needed for database work. The web app runs without it. |
| Docker | any recent | Optional, the easiest way to get Postgres. |
git clone https://github.com/YosemiteCrew/openrunic.git
cd openrunic
corepack enable
pnpm installpnpm install takes longer than you might expect the first time. pnpm-workspace.yaml sets minimumReleaseAge: 4320, which refuses any package version published in the last three days as a supply-chain guard, and pnpm 10 blocks postinstall scripts except for the six packages on the onlyBuiltDependencies allow list.
The prepare script installs husky hooks. From this point, committing runs Prettier and secret scanning on staged files, and pushing runs lint and type-check.
The web app runs in mock mode by default. It needs no database, no API, and no configuration.
pnpm --filter web devOpen http://localhost:3000. You will see the public landing page. The application itself starts at http://localhost:3000/schedule.
Mock mode is the default because apps/web/src/lib/api/config.ts resolves anything other than the literal string live to mock. Every screen reads from fixtures in apps/web/src/lib/api/mock/. The top bar shows a "Demo data" badge so nobody mistakes it for real state. See Web app for what mock mode does and does not do.
The 26-route staff application is on the
feat/emr-appbranch and has not merged todevyet. Ondev,apps/webis still the landing skeleton.
pnpm --filter api devThe API listens on port 4000 by default. Three endpoints are public:
curl http://localhost:4000/healthz
curl http://localhost:4000/fhir/metadata
curl http://localhost:4000/openapi.jsonEverything else needs a bearer token. The demo resolver accepts four synthetic tokens across two synthetic tenants:
curl -H 'Authorization: Bearer dev-clinician-a' \
'http://localhost:4000/bff/v0/patients?pageSize=5'The four tokens are dev-clinician-a, dev-frontdesk-a, dev-biller-a, and dev-clinician-b. The last one belongs to a different tenant, which makes cross-tenant behaviour easy to try by hand. See API service.
Only needed for schema work, seeding, or running the API against real storage.
Start Postgres:
docker run --name openrunic-db -e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=openrunic -p 5432:5432 -d postgres:17-alpinePrisma reads a package-local .env, not a root one:
cp packages/database/.env.example packages/database/.envFill in DATABASE_URL and DIRECT_URL. DATABASE_URL is what the application connects through and may point at a pooler. DIRECT_URL is what Prisma Migrate uses and must point straight at Postgres. Locally they are usually the same value.
Then:
pnpm --filter @openrunic/database db:generate # generate the client
pnpm --filter @openrunic/database db:deploy # apply the migration history
pnpm --filter @openrunic/database db:seed # load the demo practiceThe seed builds a deterministic synthetic practice: one organisation, facilities, staff, twenty patients, a week of appointments, encounters, notes, orders, results, charges, claims, and a verifiable audit chain. It is entirely reproducible, with no random source and no wall clock, so two runs produce byte-identical rows. It refuses to run when NODE_ENV is production unless OPENRUNIC_SEED_FORCE is set.
NEXT_PUBLIC_API_MODE=live NEXT_PUBLIC_API_BASE_URL=http://localhost:4000 pnpm --filter web devTwo things to expect. Authentication is not wired, so the web app sends no Authorization header and the API answers 401, which the screens render as an honest error state rather than hiding. And only the schedule, patients, and chart screens have a live path at all; admin, reports, orders, results, inbox, and billing stay on fixtures in either mode, because the API answers 501 for those aggregates today.
pnpm --filter @openrunic/ui storybookOpens on port 6007. 143 stories across the 22 components, with the accessibility addon enabled. See Component library.
Scope commands to what you are working on. Repo-wide runs are the slow path.
pnpm --filter <workspace> dev
pnpm --filter <workspace> lint
pnpm --filter <workspace> type-check
pnpm --filter <workspace> test
pnpm turbo run build --filter=<workspace>Workspace names: web and api for the apps; @openrunic/types, @openrunic/fhir, @openrunic/database, and @openrunic/ui for the packages. Turbo filters want the full package name; pnpm --filter accepts either.
Repo-wide:
pnpm dev # every app in dev mode
pnpm lint
pnpm type-check
pnpm test
pnpm build
pnpm verify # lint + type-check + test + build
pnpm format # Prettier write
pnpm check:secrets
pnpm doctor # react-doctor| Service | Port |
|---|---|
apps/web |
3000 |
apps/portal |
3300 |
apps/api |
4000 |
| Storybook | 6007 |
| PostgreSQL | 5432 |
- Architecture overview for the shape of the system.
- Development workflow before you open a pull request.
- Troubleshooting when something does not work. The Prisma client and mock mode account for most first-day confusion.
-
Glossary if
superbill,CARC, orplace of serviceare unfamiliar.
openrunic is an open-source operating system for human health. Pre-alpha: do not run it in production, and never put real patient data into it.
Repository · Licence (AGPL-3.0-only) · Security policy · Contributing · Code of conduct
Where this wiki and the repository disagree, the repository is right.