« All posts

Rewriting a 20,000-Line AngularJS Editor: The Real Engineering Challenge

A team rewriting a Fabric.js map editor found that the hardest problem wasn't legacy code, but a tainted canvas CORS error while building print support.

A workspace management platform's interactive office map editor had grown into a monolith dating back to the AngularJS era: a single 2,270-line controller file backed by a map engine spanning roughly 20,000 lines of TypeScript across 230+ files. The real problem wasn't line count but architectural debt—including an infinite rendering loop—that made every new feature progressively more expensive to ship. Rather than risk a big-bang rewrite, the team built a new admin module alongside the existing viewer, kept Fabric.js, and split responsibilities into a Viewport, Object Registry, and Changes Tracker, while moving the camera instead of individual objects to simplify zooming, panning, and exporting.

Unexpectedly, the hardest engineering problem wasn't Angular at all—it was implementing a print button. window.print() produced blurry output and leaked UI elements, while canvas.toDataURL() threw a tainted-canvas SecurityError because the S3-hosted floor plan image lacked proper CORS headers. The fix was to export the background image and the Fabric objects as two separate layers and recombine them for printing. A follow-up bug—objects drifting out of alignment—turned out to stem from mixing pixel-based background positioning with percentage-based object positioning; standardizing on percentages resolved it instantly.

After the migration, the codebase didn't shrink—new capabilities like draft support, safe publishing, and multiple workspace modes were added instead. The real win was that shipping new features no longer felt risky. The team's key takeaway: the hardest complexity rarely lives inside a single framework, but in the gaps between browser rendering behavior, CORS, and coordinate systems.

» SourceDev.to