Verisurf makes 3D metrology software. The core product is a Windows desktop application built on C++ and MFC (Microsoft Foundation Classes), a framework from the ’90s that still powers mission-critical measurment systems in aerospace, automotive, and manufacturing. I’ve been building on top of it since 2014.
The question I kept coming back to was how to build modern tooling on a legacy desktop app without rewriting it. My answer was a layered architecture that progressively modernized the interface while leaving the core alone.
Layer 1: the REST API bridge
Step one was exposing Verisurf’s internal functionality through a REST API. That gave any modern application, whether web, mobile, or desktop, a clean interface to device control, measurement commands, inspection plans, and data import.
// Modern web app talking to legacy MFC desktop// via REST API bridge layerconst measurePoint = async (deviceId, planId) => { // API translates REST call to Verisurf COM interface const result = await fetch('/api/v1/measure', { method: 'POST', body: JSON.stringify({ deviceId, planId }) }); // Real-time inspection data back to web UI return result.json(); // { x, y, z, deviation, status }};Layer 2: companion apps in Electron
With the API in place, I built Electron companion apps that run alongside the MFC application: modern UI for notifications, real-time inspection data, and workspace management, talking to the core over the REST API and WebSocket streams.
- Verilectron Main companion app wrapping core API functionality
- VS Notify React-based notification system for build events
- LiveReport DRO Real-time auto-inspect results display
- Workspace Selector Modern workspace management UI
Layer 3: AI integration
The latest layer adds AI on top of the bridge. An AI assistant built on Azure OpenAI (GPT-4) interprets natural-language commands and translates them into API calls. A separate Copilot integration generates measurement report templates inside Excel add-ins, which is the project that finished runner-up at Sandvik’s global hackathon.
// Natural language to Verisurf API command translationconst processCommand = async (input: string) => { const intent = await classifyIntent(input); switch (intent.action) { case 'measure': return api.measure(intent.params); case 'inspect': return api.runPlan(intent.planId); case 'report': return api.exportData(intent.format); case 'calibrate': return api.calibrate(intent.deviceId); }};The pattern
The takeaway isn’t specific to Verisurf. You don’t need to rewrite legacy software to give it a modern interface: build an API bridge, layer modern UIs on top, then add AI. Each layer keeps the reliability of what came before while expanding what the system can do. The same sequence, expose, wrap, augment, applies to most legacy systems.