Work with FHIR data as if it were files on your filesystem.
Imagine a world where your FHIR server is just a folder on your computer. You can:
- π Edit FHIR resources with your favorite text editor
- π Copy data between servers with
cp - π§ Script with standard bash commands
- π Search with
grep,find, andjq
Sounds too good to be true? Thanks to Filesystem in Userspace (FUSE), it's real. FHIR FUSE creates a virtual filesystem that mirrors your FHIR server's data, making healthcare interoperability as simple as working with files.
Project status: proof of concept
The easiest way to get started is using Docker Compose, which includes everything you need:
# Build binary for Linux ARM64
make build-linux-musl-arm64
# Start all services (PostgreSQL, Aidbox FHIR server, and FHIR-FUSE)
docker-compose up -d
# Access the mounted FHIR filesystem
# On Linux: ls ./mnt/Patient
# On macOS: see below for workarounds
docker exec fhir-fuse-fhir-fuse-1 ls /mnt/fhir/Patient
β οΈ WarningYou need to initialize the Aidbox instance by nagivating to http://localhost:8080 and logging in.
What's included:
- π PostgreSQL - Database backend for Aidbox
- π₯ Aidbox - Full-featured FHIR R4 server
- π FHIR-FUSE - Alpine-based container with FUSE filesystem
Due to Docker Desktop's VM architecture, FUSE mounts cannot propagate directly to the macOS host. However, there are simple workarounds:
# Install macFUSE
brew install macfuse
# Build and run natively
cargo build --release
./target/release/fhir-fuse /tmp/fhir http://localhost:8080/fhir
# Access files directly on your Mac
ls /tmp/fhir/Patient
cat /tmp/fhir/Patient/<id>.json | jq .# Start Docker services
docker-compose up -d
# Access files inside container (no scripts needed, just docker exec)
docker exec fhir-fuse-fhir-fuse-1 ls /mnt/fhir/Patient
docker exec fhir-fuse-fhir-fuse-1 cat /mnt/fhir/Patient/<id>.json | jq .
# Or copy files to host
docker cp fhir-fuse-fhir-fuse-1:/mnt/fhir ./mntSee MACOS_LIMITATIONS.md for detailed explanations and additional workarounds.
For comprehensive usage instructions, see USAGE.md.
# Build for your current platform
cargo build --release
# Cross-compile for all platforms (uses Docker with caching)
make build-allPerformance Note: Cross-compilation uses Docker volume caching. First build takes ~8 minutes, subsequent builds only ~45 seconds!
If you encounter "transport endpoint is not connected" errors:
# Restart the FHIR-FUSE container
docker-compose restart fhir-fuse
# Or if running natively on macOS/Linux
umount /tmp/fhir # or fusermount -u /tmp/fhir
./mount.shSee TROUBLESHOOTING.md for a complete troubleshooting guide.
To build and run FHIR FUSE, you need FUSE libraries and pkg-config. A default FUSE installation is usually sufficient.
FUSE is available in most Linux distributions as fuse or fuse3 (both are compatible).
Debian/Ubuntu:
sudo apt-get install fuse3 libfuse3-dev pkg-configCentOS/RHEL:
sudo yum install fuse-devel pkgconfigInstall macFUSE using Homebrew:
brew install macfuse pkgconfNote: macOS 10.9+ required. On Apple Silicon Macs, you may need to enable third-party kernel extensions.
nix-env -iA nixos.macfuse-stubs nixos.pkg-config
export PKG_CONFIG_PATH=${HOME}/.nix-profile/lib/pkgconfigpkg install fusefs-libs pkgconfEach FHIR resource type has its own directory, with individual resources as JSON files:
./mnt/ # Mount point
βββ Patient/ # Resource type directory
β βββ patient-id-1.json # Each file is a FHIR resource
β βββ patient-id-2.json # Filename matches resource ID
βββ Observation/
β βββ observation-id-1.json
β βββ observation-id-2.json
βββ Practitioner/
βββ ... # All FHIR R4 resource types
Work with FHIR resources using standard file operations:
- Create:
echo '{"resourceType":"Patient",...}' > ./mnt/Patient/new-patient.json - Read:
cat ./mnt/Patient/patient-id-1.json - Update: Edit the file with any text editor
- Delete:
rm ./mnt/Patient/patient-id-1.json
Access historical versions of resources through hidden dot folders:
./mnt/
βββ Patient/
β βββ patient-id-1.json # Current version
β βββ .patient-id-1/ # Hidden history folder
β β βββ patient-id-1.v1.json # Version 1
β β βββ patient-id-1.v2.json # Version 2
β β βββ patient-id-1.v3.json # Version 3
β βββ patient-id-2.json
βββ Observation/
β βββ observation-id-1.json
β βββ .observation-id-1/
β βββ observation-id-1.v1.json
β βββ observation-id-1.v2.json
Usage:
# View current version
cat ./mnt/Patient/patient-id-1.json
# View version history
ls ./mnt/Patient/.patient-id-1/
# Compare versions
diff ./mnt/Patient/.patient-id-1/patient-id-1.v1.json \
./mnt/Patient/.patient-id-1/patient-id-1.v2.jsonPerform FHIR searches by creating directories with search parameters:
./mnt/
βββ Patient/
β βββ _search/ # Search directory
β β βββ name=John/ # Simple search
β β β βββ Patient/
β β β βββ patient-1.json
β β β βββ patient-2.json
β β βββ birthdate=gt1990-01-01&gender=male/ # Complex search
β β βββ Patient/
β β βββ patient-3.json
β βββ patient-1.json
β βββ patient-2.json
βββ Observation/
β βββ _search/
β β βββ _include=Observation:patient&_include:iterate=Patient:link/
β β βββ Observation/ # Search results include
β β β βββ observation-1.json # related resources
β β β βββ observation-2.json
β β βββ Patient/ # via _include
β β βββ patient-1.json
β β βββ patient-2.json
β βββ observation-1.json
β βββ observation-2.json
Usage:
# Create a search directory (mkdir triggers the search)
mkdir -p "./mnt/Patient/_search/name=Smith"
# View search results
ls "./mnt/Patient/_search/name=Smith/Patient/"
# Complex searches with multiple parameters
mkdir -p "./mnt/Observation/_search/code=http://loinc.org|85354-9&date=gt2023-01-01"
ls "./mnt/Observation/_search/code=http://loinc.org|85354-9&date=gt2023-01-01/Observation/"Execute FHIR operations through special $operation directories:
./mnt/
βββ Patient/
β βββ $validate/ # Operation directory
β βββ resource-id/ # Operation parameters
β βββ result.json # Operation result
βββ ViewDefinition/
βββ $run/
β βββ view-id.json # Touch to execute, read for results
β βββ view-id.csv # Different output formats
βββ patient_demographics.json # ViewDefinition resources
βββ blood_pressure.json
# List available ViewDefinitions
ls ./mnt/ViewDefinition/
# Execute a ViewDefinition (touch creates the operation)
touch "./mnt/ViewDefinition/\$run/patient_demographics.json"
# Read the results
cat "./mnt/ViewDefinition/\$run/patient_demographics.json" | jq .
# Get results in CSV format
touch "./mnt/ViewDefinition/\$run/patient_demographics.csv"
cat "./mnt/ViewDefinition/\$run/patient_demographics.csv"Equivalent REST API:
POST /fhir/ViewDefinition/patient_demographics/$run
Content-Type: application/json
Accept: application/json
{
"resourceType": "Parameters",
"parameter": [{
"name": "_format",
"valueCode": "json"
}]
}# Copy all patients from one server to another
cp -r /mnt/source-server/Patient/* /mnt/destination-server/Patient/# Backup all observations to a tar archive
tar -czf observations-backup.tar.gz /mnt/fhir/Observation/
# Export specific resources
cp /mnt/fhir/Patient/patient-123.json ./backups/# Count resources by type
find /mnt/fhir -name "*.json" | wc -l
# Extract specific fields with jq
cat /mnt/fhir/Patient/*.json | jq '.name[0].family'
# Search for patterns
grep -r "diabetes" /mnt/fhir/Condition/# Batch update resources
for file in /mnt/fhir/Patient/*.json; do
jq '.active = true' "$file" > "$file.tmp" && mv "$file.tmp" "$file"
done
# Monitor changes
watch -n 5 'ls -l /mnt/fhir/Patient/'# Quickly inspect test data
cat /mnt/fhir/Patient/test-patient-1.json | jq .
# Create test fixtures
cp /mnt/fhir/Patient/example.json ./test/fixtures/
# Validate resources
for file in /mnt/fhir/Patient/*.json; do
jq empty "$file" || echo "Invalid JSON: $file"
done- π Full CRUD Support - Create, read, update, and delete resources as files
- π Version History - Access historical versions through hidden folders
- π FHIR Search - Execute searches by creating directories
- β‘ FHIR Operations - Run
$validate,$run, and other operations - π Include Support - Search results include related resources via
_include - π₯ FHIR R4 Compliant - Works with any FHIR R4 server
- π³ Docker Ready - Includes complete Docker Compose setup
- π Cross-Platform - Linux, macOS, and FreeBSD support
- π High Performance - Efficient caching and lazy loading
- π οΈ Standard Tools - Use
ls,cat,grep,jq, and more
- QUICKSTART.md - Get started in 5 minutes
- USAGE.md - Comprehensive usage guide
- IMPLEMENTATION.md - Technical implementation details
- TROUBLESHOOTING.md - Common issues and solutions
- MACOS_LIMITATIONS.md - macOS-specific workarounds
- DOCKER.md - Docker deployment guide
- MOUNT_PROPAGATION.md - How mount propagation works
Contributions are welcome! Please feel free to submit issues and pull requests.
This project is open source. See the LICENSE file for details.
Built with:
- fuse-rust - Rust bindings for FUSE
- Aidbox - FHIR server platform
- FHIR R4 - Fast Healthcare Interoperability Resources
Made with β€οΈ for the healthcare interoperability community