π API reference β the full component props, imperative ref, and /core exports. Documentation per language:
π¬π§ English Β· π©πͺ Deutsch Β· πͺπΈ EspaΓ±ol Β· ππΊ Magyar
DenCT is an embeddable dental CBCT / CT DICOM viewer for React + TypeScript. Load several CTs at once and switch between them; MPR and true-3D views (with render presets, colormaps and a low/medium/high quality control), panoramic (OPG) reconstruction along the dental arch, perpendicular cross-sections, guided implant planning with nerve/sinus/neighbour safety clearances and bone quality (Misch D1βD5), a printable drill-guide (STL) export, and configurable image (PNG/JPG) and PDF report exports β all in a 4-language UI (EN/DE/ES/HU). Everything runs locally in the browser β no upload. Built on Cornerstone3D and vtk.js.
π Repository: https://github.com/ZoliQua/Dental-CBCT-Viewer
npm install dental-cbct-viewer react react-domRequirements: React 18 or 19 (peer dependency); a bundler that supports the exports field, ESM, Web Workers and WASM (Vite, webpack 5, Next.js, Rollup). The heavy imaging libraries (Cornerstone3D, vtk.js, jsPDF, dicom-parser) are regular dependencies and are installed for you.
β οΈ Cross-origin isolation. The DICOM decode workers useSharedArrayBuffer, so the host page must be served with:Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corpWithout these headers, image decoding will not run.
Render DicomViewer and import the stylesheet once:
import { DicomViewer } from "dental-cbct-viewer";
import "dental-cbct-viewer/style.css";
export function Planner() {
return (
<div style={{ height: "100vh" }}>
<DicomViewer lang="en" />
</div>
);
}The viewer fills its parent, so give it a sized container. Dark mode is the default and is scoped to the viewer's own root β it never touches the host page's theme.
import { useRef } from "react";
import { DicomViewer, type DicomViewerHandle } from "dental-cbct-viewer";
import "dental-cbct-viewer/style.css";
function App() {
const ref = useRef<DicomViewerHandle>(null);
return (
<>
<button onClick={() => ref.current?.loadSample()}>Load sample</button>
<button onClick={() => ref.current?.exportPdf()}>Export PDF</button>
<DicomViewer
ref={ref}
initialLayout="1+3"
onImplantsChange={(implants) => console.log(implants.length, "implants")}
onPlanChange={(plan) => localStorage.setItem("plan", JSON.stringify(plan))}
/>
</>
);
}Handle methods: getImplants, addImplant, updateImplant, removeImplant, getPlan, loadPlan, loadStudy(files), loadSample, setLayout, setActiveView, exportPdf, exportGuideStl.
Props: patientId, patientName, initialPlan, initialLayout, lang, onPlanChange, onImplantsChange, className, embedded.
Pure, React-free building blocks run in Node, tests or your own logic β the implant data model + system catalog and all the geometry/analysis math:
import {
IMPLANT_SYSTEMS, getImplantSystem, // implant catalog
implantWorldAxis, evaluateImplant, // geometry + nerve/sinus/neighbour safety
classifyBone, sampleImplantBoneHU, // Misch D1βD5 bone quality
} from "dental-cbct-viewer/core";The heavy CSG kernel (drill-guide Boolean via manifold-3d) is loaded lazily, so importing /core for the geometry/safety helpers stays light.
- ποΈ Multi-study β load several CTs (DICOM folders,
.dcmfiles, GALILEOS and OneVolume/Morita folders) into a left-panel series tree and switch between them instantly; each study keeps its own plan - π§ True-3D volume rendering with render presets (incl. translucent X-ray), colormaps (Grayscale / Cool / Warm / Spectral / Inverted) and a Low/Medium/High quality control, intersecting slice planes and a crop box
- π©» MPR (axial / sagittal / coronal) with linked crosshairs, plus panoramic (OPG) reconstruction and tiltable cross-sections along a draggable dental arch curve
- π¦· Guided implant planning β 3D implant + drill sleeve, nerve / sinus / neighbour safety clearances, bone quality (Misch D1βD5, indicative class from uncalibrated CBCT gray values at the implant site)
- π¨οΈ Printable drill guide (STL) via constructive solid geometry (
manifold-3d). The exported guide has no integrated drill stop and no metal sleeve, and tissue fit requires a registered surface scan β verify the fit on a printed model before any clinical use. - πΌοΈ Image export (PNG/JPG) β pick views, resolution, on-image info to burn in, separate files or one grid β and a configurable PDF report (toggle header fields and sections, portrait/landscape; jsPDF with a bundled Unicode font so Hungarian accents render)
- π Plan save/load (JSON), imperative ref API, controlled props/callbacks
- π 100% local β DICOM parsing, rendering and exports run in the browser; nothing is uploaded
- π 4 UI languages (EN / DE / ES / HU) Β· π self-scoped dark mode Β· π§± embeddable
- Vite: works out of the box.
- Next.js / webpack 5: render the viewer in a client component (
"use client") β it reads the DOM on mount. Ensure the COOP/COEP headers above are set (e.g. vianext.config.jsheaders). Worker/WASM assets are pre-bundled into the package.
- No network egress. The viewer never uploads scans or patient data β all parsing, rendering and exports happen in the browser. It contacts no analytics or third-party host; the only
fetchis for its own bundled sample asset. Exported PDF/PNG/STL/plan files are user-initiated downloads. - Untrusted input is bounded. Decompression enforces an output budget (gzip-bomb safe), the native-volume decoders validate geometry against hard caps before allocating, and plan JSON is parsed with a strict field allowlist (no prototype pollution).
- Content-Security-Policy. The hosted demo ships a strict CSP (
connect-src 'self',object-src 'none', nounsafe-evalfor scripts). When you embed the component, set an appropriate CSP on your host page β the library needsscript-src 'wasm-unsafe-eval'andworker-src blob:for the WASM decode workers, plus the COOP/COEP headers below.
MIT Β© ZoltΓ‘n Dul. Bundled Roboto font under Apache-2.0 (see LICENSE).
Medical disclaimer: research/demonstration software only β not a certified medical device and not for clinical diagnosis, treatment planning, precise measurement or implant workflows.