DEV Community

TJ
TJ

Posted on

Modernizing Cephalometric Analysis: Building a Web App for Orthodontic Diagnostics

The Problem: When Legacy Code Meets Modern Needs

The original cephalometric analysis tool worked, but it was slow. 30+ second build times, sluggish UI, and technology from 2018. As a developer working in healthcare technology, I modernized this legacy application - and the results were dramatic.

The results: 30+ second builds → <1 second HMR, 100% class components → modern React hooks, and 100% backward compatibility maintained. The result is Ortho Cephalometry.

What is Cephalometric Analysis?

Cephalometric analysis is the science of measuring facial structures - how teeth, jaws, and facial bones relate to each other. Orthodontists use lateral cephalogram X-rays to:

  • Measure angles and distances between anatomical landmarks
  • Assess skeletal and dental relationships
  • Plan treatment (braces, aligners, surgery)
  • Track progress over time

The analysis involves placing specific points on X-ray images and calculating measurements using methods like Downs Analysis, Steiner Analysis, Tweed's Triangle, and more. Accuracy and speed matter - these measurements directly impact treatment decisions.

The Modernization Journey

Before → After

Original Stack (from 2018):

  • Webpack 4 (30+ second builds)
  • React 16 (class components)
  • TypeScript 2.9
  • TSLint (deprecated)
  • node-sass
  • MobX 5

Modern Stack:

  • Vite 5 - <1 second HMR
  • React 18 - Functional components with hooks
  • TypeScript 5 - Better type inference
  • ESLint - Modern linting
  • Sass (Dart Sass) - Latest compiler
  • MobX 6 - Latest state management

Key Improvements

  1. Build Times: 30+ seconds → <1 second for HMR
  2. Component Architecture: 100% migration to functional components with hooks
  3. Type Safety: TypeScript 5 caught several bugs during migration
  4. Developer Experience: Comprehensive Makefile for easy project management

The Challenge: 100% Backward Compatibility

We maintained complete compatibility - same file format, same iframe protocol, identical analysis results. Users can migrate without losing any data. Zero breaking changes.

Features

  • Interactive Point Placement: Upload X-rays and place anatomical points with drag-and-drop
  • 9+ Analysis Methods: Downs, Steiner, Tweed, Wits, and more
  • Save & Load: .cephalometric format for tracking patients over time
  • Export: PNG export for patient reports
  • Embeddable: iframe support for integration into larger systems

Technical Highlights

MobX 6 for reactive state management - when points are placed, calculations update automatically:

import { observer } from 'mobx-react-lite';

export const Main = observer(() => {
  // Automatically re-renders when observable data changes
  return <AnalysisView />;
});
Enter fullscreen mode Exit fullscreen mode

Modern React Hooks - clean, testable code:

useEffect(() => {
  window.onmessage = function (e) {
    if (e.data?.startsWith('cephalometric-open:')) {
      data.loadProject(parseProjectData(e.data));
    }
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

TypeScript 5 caught several undefined point errors during migration that would have been runtime bugs.

Getting Started

Prerequisites

  • Node.js 18+ and npm
  • Make (usually pre-installed on Unix-like systems)

Quick Start

# Clone and install
git clone https://github.com/tjandrayana/ortho-cephalometry.git
cd ortho-cephalometry
make install

# Run dev server (background)
make dev-bg

# Check status, view logs, or stop
make status
make logs
make stop
Enter fullscreen mode Exit fullscreen mode

The app runs at http://localhost:3000 with instant HMR thanks to Vite.

Key Makefile Commands: make install, make dev-bg, make build, make preview, make lint, make clean

Alternative: Use npm scripts directly (npm install, npm run dev, etc.)

Project Structure

ortho-cephalometry/
├── src/
│   ├── data/              # MobX state management
│   ├── literature/         # Cephalometric definitions
│   │   ├── analysis/      # Analysis methods
│   │   ├── angles.ts      # Angle definitions
│   │   ├── distances.ts   # Distance measurements
│   │   └── points.ts      # Point definitions
│   ├── view-components/   # React components
│   └── main.tsx           # Entry point
├── Makefile               # Build automation
└── vite.config.ts         # Vite config
Enter fullscreen mode Exit fullscreen mode

Migration Notes

100% backward compatible - existing .cephalometric files work perfectly. Same file format, same iframe protocol, identical analysis results. Users can migrate seamlessly.

Use Cases

  • Orthodontic Clinics: Daily diagnostic analysis
  • Dental Schools: Educational tool for teaching
  • Research: Data collection and analysis
  • Practice Management: iframe integration into larger systems

Lessons Learned

What worked: Vite over Webpack (build time improvement was huge), sticking with MobX (perfect for reactive calculations), the Makefile (small QoL improvements matter), 100% backward compatibility (zero migration pain).

What I'd do differently: Start with TypeScript 5 directly (incremental upgrade was slower), convert components in batches (more efficient), add more tests before migration (would catch issues earlier).

Conclusion

Modernizing this application created a tool that saves time, reduces errors, improves maintainability, and enhances developer experience. The result serves the orthodontic community while being a pleasure to develop with.

If you're working in healthcare technology or modernizing legacy applications, I hope this project serves as a useful reference. The techniques apply to any legacy React application.

Check it out: Repository | Original Project | Original Demo

Note: This tool is intended for professional use by qualified dental professionals. Always ensure proper training and understanding of cephalometric analysis before using in clinical practice.


Top comments (0)