A FHIRPath language server that runs entirely in the browser.
No server process, no WebSocket connections — just a Web Worker providing autocompletion, diagnostics, hover information, and go-to-definition for FHIRPath expressions in CodeMirror editors.
pnpm add @health-samurai/aidbox-fhirpath-lspPeer dependencies: react, react-dom, @codemirror/lsp-client, @codemirror/state.
The LSP server runs in a Web Worker and communicates with CodeMirror via a MessageChannel.
FHIR type information (StructureDefinitions) is resolved through the Aidbox client and cached in IndexedDB so subsequent loads are fast.
CodeMirror ←→ LSP Transport (MessageChannel) ←→ Web Worker (FHIRPath LSP)
↕
Aidbox Client → FHIR Server
↕
IndexedDB Cache
- Autocompletion — Context-aware suggestions for FHIRPath functions, fields, and resource types
- Diagnostics — Real-time validation and error highlighting
- Hover — Inline type information and documentation
- Go-to-definition — Jump to type definitions
- Find references — Locate all usages
- Code actions — Quick fixes and suggestions
- Context type prefix — With a resource type set (e.g.
Patient), expressions likename.first()work without thePatient.prefix - IndexedDB caching — StructureDefinitions are cached locally to avoid redundant network requests
import { useCodeMirrorLsp } from "@health-samurai/aidbox-fhirpath-lsp";
import { AidboxClient } from "@health-samurai/aidbox-client";
function FhirPathEditor() {
const { extension, setContextType } = useCodeMirrorLsp(client, {
contextType: "Patient",
debug: false,
});
// `extension` goes into the CodeMirror editor setup
// `setContextType("Observation")` switches context dynamically
}import { createCodeMirrorLsp } from "@health-samurai/aidbox-fhirpath-lsp";
import { EditorState } from "@codemirror/state";
const { extension, setContextType } = createCodeMirrorLsp(client, {
contextType: "Patient",
});
const state = EditorState.create({
doc: "name.where(use = 'official').first()",
extensions: [
// ... other CodeMirror extensions
extension,
],
});The wrapCache helper adds IndexedDB caching to resolve/search functions:
import { wrapCache } from "@health-samurai/aidbox-fhirpath-lsp";
const cachedCallbacks = wrapCache({
resolve: (typeName) => fetchStructureDefinition(typeName),
search: (kind) => searchStructureDefinitions(kind),
});| Method | Description |
|---|---|
textDocument/completion |
Autocomplete suggestions |
textDocument/hover |
Type info and documentation |
textDocument/definition |
Jump to definition |
textDocument/references |
Find all references |
textDocument/publishDiagnostics |
Error and warning markers |
textDocument/documentSymbol |
Document outline |
textDocument/codeAction |
Quick fixes |
cd packages/aidbox-fhirpath-lsp
pnpm build # Build library + worker
pnpm tsc:check # Type-check
pnpm lint:fix # Lint and format with BiomeThe worker is built separately by Vite as a standalone ES module (see vite.config.ts).