# Medplum: An Open Source FHIR Platform for Building Healthcare Apps

> Medplum is an Apache-2.0 TypeScript platform that combines a FHIR clinical data repository, OAuth and SMART-on-FHIR auth, server-side Bots and a React component library. It suits teams building custom healthcare software, not clinics looking for a finished EHR.

**medplum/medplum** — Medplum is a healthcare platform that helps you quickly develop high-quality compliant applications.

- Repository: https://github.com/medplum/medplum
- Website: https://medplum.com
- Stars: 2,701 · Forks: 959
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/medplum-medplum

## The Problem Medplum Solves, and Who It Is Actually For

Healthcare software rarely fails because the UI is hard. It fails because the data layer is hard. Patient records, observations, encounters and questionnaires have to live in a standard format, be reachable through an API that other systems understand, and be protected by an auth model that satisfies an auditor. Building that from scratch means writing a FHIR server, an identity layer and a component library before you write a single feature that a clinician would recognise.

Medplum's answer is to ship all three. The README describes it as a developer platform that enables flexible and rapid development of healthcare apps, and lists the parts: Medplum Auth for OAuth, OpenID and SMART-on-FHIR; the Clinical Data Repository that hosts data in a standards-based store; a FHIR-based API; client SDKs; a web app for viewing and editing data; Bots for server-side logic; and a React component library.

The intended reader is a developer, not a clinician. The repository is a monorepo of TypeScript packages, and the README states plainly that this codebase is not a typical open source project because it is the entire product rather than a library with a limited scope. That sentence tells you who the project is for and who it is not for. If you want to install an EHR and start booking appointments, this is the wrong shape of software. If you are building the appointment system, the pieces are already there.

## How the Repository Is Put Together

The README's folder listing shows a workspace monorepo. Under packages you find agent (an on-premise agent), app (the frontend), bot-layer (an AWS Lambda layer for Bots), cdk (AWS CDK infrastructure as code), cli, core, definitions, docs, examples, fhir-router, fhirtypes, generator, graphiql, hl7 and mock, among others. The root package.json declares workspaces for packages/* and examples/*, and the build script uses turbo to filter out the docs, storybook and example workspaces.

The technology list is short and conventional: PostgreSQL for data storage, Redis for background jobs and caching, Express for the API server, TypeScript for the language and React for the frontend. A separate fhir-router package handles FHIR URL routing, which is the piece that makes the API speak FHIR rather than a bespoke REST dialect.

The examples directory is the most useful part for evaluating fit. It contains runnable projects including medplum-hello-world, medplum-provider, medplum-patient-intake-demo, medplum-smart-on-fhir-demo, medplum-demo-bots, medplum-fhircast-demo, medplum-websocket-subscriptions-demo and medplum-local-k8s. Each one is a worked example of a pattern the platform expects you to use. If a pattern you need has no example, that is a signal about how well trodden the path is.

## Installing Medplum Locally with Docker and Postgres

The repository ships a docker-compose.yml whose header comment says it runs Medplum's required background services, and that it can quickly run two services: the Postgres database and the Redis cache. You start it from the repository root.

```bash
docker-compose up
```

The compose file pins postgres:16 and redis:7, exposes port 5432 for Postgres and 6379 for Redis, and creates a named volume called medplum-postgres-data. The credentials in the file are POSTGRES_USER=medplum and POSTGRES_PASSWORD=medplum, and Redis is started with redis-server --requirepass medplum. Those are development defaults written into the file; they are not secrets you should carry into a deployed environment. The file also mounts ./postgres/postgres.conf and the ./postgres/ directory into the container's init directory, so schema initialisation happens on first start.

The Dockerfile is a separate concern. It is described as the production Dockerfile and it depends on two archives produced by scripts/build-docker-server.sh: medplum-server-metadata.tar.gz and medplum-server-runtime.tar.gz. It builds in two stages on dhi.io/node:24.18-dev and dhi.io/node:24.18, installs production dependencies with npm ci --omit=dev, and exposes ports 5000 and 8103. The entrypoint runs Node with an OpenTelemetry instrumentation hook before loading packages/server/dist/index.js. You cannot build that image directly from a clean checkout without first running the build script, which the README does not walk through.

For contributors, the README points to the local setup instructions at medplum.com/docs/contributing/local-dev-setup rather than repeating them. That is where the actual first-run sequence lives. A docker-compose.full-stack.yml also exists at the root for running more than the two background services.

## Contributing Is Gated, and That Changes the Calculus

This is the part most people miss when they skim the README. Code contributions go through an approval system: a pull request must be linked to an issue labelled open-to-community before maintainers will review it. The README states that PRs not linked to such an issue are automatically closed, though they can be reopened once the link is added. Established contributors and Medplum team members are exempt.

The practical consequence is that you cannot fork this repository, fix a bug you hit, and expect the fix upstream without first finding or opening an issue and asking for the label. The README tells you to look for an existing open-to-community issue, or open a new one and ask for the label, before starting work on a fix. For a new feature, it asks you to open an issue first to discuss how it might work and whether it fits the roadmap.

Whether that is reasonable depends on your situation. It keeps the maintainers from drowning in unsolicited patches to a codebase they describe as their entire product. It also means the open source label here describes the licence and the visibility of the code more than it describes open governance. The DCO applies to contributions. There is a good first issue label for newcomers, and documentation contributions are explicitly welcomed through Markdown files in packages/docs/docs, with GitHub.dev offered as a way to edit without cloning.

## Where Medplum Is the Wrong Tool

The clearest limitation is scope. Medplum gives you primitives: a data repository, an API, auth, a component library, a place to run server-side logic. It does not give you a finished clinical workflow. The README's own framing, that this is the entire product rather than a library, cuts both ways. You inherit a platform's opinions and its release cadence, and you take on the work of assembling an application on top of it.

The operational requirements are not optional. PostgreSQL and Redis are both listed as core technologies, and the docker-compose file exists precisely because those services are required. If your environment cannot run Redis, or your team has standardised on a different database, the local development path described here does not apply to you without substitution work that the README does not document.

The production Dockerfile has a build-order dependency that is easy to trip over: it expects archive files that a build script produces, and those archives are not in the repository. Anyone expecting docker build . to work against a fresh clone will be disappointed, and the README does not document that sequence. That is a real friction point for a platform aimed at developers.

Finally, consider the compliance framing carefully. The repository topics include hipaa and soc2, and the project describes the CDR as secure and compliant. Compliance is a property of a deployed system and its operating organisation, not of a source repository. Nothing in the project's public description tells you what you would need to do to make your own deployment compliant.

## Medplum Compared with a Bare FHIR Server

The obvious alternative is to run a standalone FHIR server and build the rest yourself. HAPI FHIR is the reference point that people reach for, and the search data shows medplum vs hapi is a question people actually ask. The difference in approach is architectural rather than a matter of feature lists.

A standalone FHIR server answers one question: how do I store and retrieve FHIR resources over HTTP. You then choose your own identity provider, write your own React components, and host your own job runner. Medplum bundles those decisions. Medplum Auth handles OAuth, OpenID and SMART-on-FHIR in the same product as the data repository, the SDKs sit in the same monorepo as the API, and Bots give you a place to run server-side logic without standing up a separate compute tier. The bot-layer package exists specifically to package Bots as an AWS Lambda layer.

That bundling is the trade. You get fewer integration seams and a consistent TypeScript surface from the SDK through to the React components. You also get a platform whose release train you do not control, and whose contribution process is gated. If your team already has an identity provider, a component library and a job runner it trusts, the value of the bundle drops sharply, and a bare FHIR server plus your existing stack may be the smaller commitment. If you are starting from nothing, the bundle is most of the reason to choose Medplum.

## Licence, Releases and What Maintenance Costs You

Medplum is licensed under Apache-2.0, and the repository carries a NOTICE file alongside LICENSE.txt. Apache-2.0 permits commercial use and modification, and it includes a patent grant. It also carries obligations, including preserving licence and notice files in distributed copies and stating significant changes. This is not legal advice; if you redistribute Medplum inside a product, have counsel read LICENSE.txt and NOTICE rather than relying on a summary.

The release cadence visible in the repository is frequent: v5.1.40, v5.1.39 and v5.1.38 all landed within ten days of each other in September 2026, and the last push to main was on 2026-09-24. The root package.json version tracks the release, currently 5.1.40, and it pins a large set of transitive dependencies through an overrides block covering packages such as esbuild, typescript, uuid and whatwg-url. That overrides block is where upgrade work concentrates: when you pull a new release, those pins may move, and the TypeScript version pinned there is 6.0.3.

The practical upgrade cost is the monorepo itself. The build runs through turbo across workspaces, and the root scripts filter out docs, storybook and examples for the standard build. If you consume Medplum as packages rather than as a fork, your exposure is the published npm packages such as @medplum/core, whose version badge the README displays. If you fork, you own the whole build, including the archive-generation step the production Dockerfile depends on. The README does not document a rollback procedure for a failed upgrade, so plan your own.

## Conclusion

Adopt Medplum if you are a product team building a custom healthcare application and want a FHIR data layer, auth and React components you do not have to write yourself; the Apache-2.0 licence and the docker-compose file give you a path to run it locally before committing. Do not adopt it if you need a finished, configurable EHR for a clinic, or if you cannot run PostgreSQL and Redis. Before committing, verify the local setup instructions in the contributing docs, confirm which packages your application actually imports, and read NOTICE alongside LICENSE.txt.

## FAQ

### Is Medplum open source?

Yes. The repository is licensed under Apache-2.0 and the code is public on GitHub, with a NOTICE file alongside LICENSE.txt. Note that code contributions are gated: pull requests must be linked to an issue labelled open-to-community before maintainers review them.

### Is Medplum an EHR?

The README describes Medplum as a developer platform for building healthcare apps, not as a finished EHR. It provides a clinical data repository, a FHIR API, auth, Bots and React components that you assemble into an application.

### What does Medplum do?

It bundles Medplum Auth for OAuth, OpenID and SMART-on-FHIR, a Clinical Data Repository holding healthcare data, a FHIR-based API with client SDKs, a web app for viewing and editing data, server-side Bots, and a React component library. The repository is a TypeScript monorepo built on PostgreSQL, Redis, Express and React.

### How does Medplum compare with HAPI FHIR?

Medplum bundles the data repository, auth, SDKs, Bots and React components into one platform, while a standalone FHIR server answers only the storage and retrieval question and leaves identity, UI and job execution to you. The trade is fewer integration seams against a release train you do not control.

## Sources

- [License: Apache-2.0](https://github.com/medplum/medplum/blob/main/LICENSE)
- [medplum/medplum on GitHub](https://github.com/medplum/medplum)
- [Project website](https://medplum.com)
- [README](https://github.com/medplum/medplum/blob/main/README.md)
- [Releases](https://github.com/medplum/medplum/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/medplum-medplum
