Death to Spreadsheets

November 2020

JavaScript Architecture DAG

I've spent a significant portion of my career converting spreadsheets into web applications. If you've worked in enterprise software long enough, you know exactly what I'm talking about. Somewhere in every organization, there's a subject matter expert with an Excel file that runs a critical business process. It has 47 tabs, formulas referencing cells three sheets away, and conditional formatting that would make your eyes bleed.

At Berkadia, this pattern reached its peak. We were in commercial real estate, an industry where property valuations, loan calculations, and risk assessments had been refined over decades in spreadsheets. These weren't simple files - they were intricate webs of business logic that SMEs had perfected over years of iteration.

The Problem

The typical workflow looked like this: a subject matter expert would hand us a spreadsheet. Our job was to understand every formula, every dependency, every edge case - and rebuild it all as a web application. The frontend would need to mirror the spreadsheet's behavior, and the backend would need to perform the same calculations for validation and persistence.

This meant:

  • Manually translating Excel formulas into JavaScript
  • Duplicating calculation logic between frontend and backend
  • Rebuilding the dependency graph that Excel handles automatically
  • Testing extensively to ensure parity with the original spreadsheet
  • Dealing with SME changes that required updating multiple codebases

Every cell in a spreadsheet is essentially a node in a directed acyclic graph (DAG). Cell A1 might depend on B2 and C3, which in turn depend on other cells. Excel handles this graph automatically - when you change a value, it knows exactly what needs to recalculate and in what order. We were manually rebuilding this behavior every single time.

The Solution: GraphLib

I got tired of doing the same translation work over and over. So I built GraphLib - a library that could take a spreadsheet and convert it into a directed graph of JavaScript nodes that we could execute on both the frontend and backend.

The core idea was simple:

  • Parse the spreadsheet and extract all formulas and their dependencies
  • Build a DAG representing the calculation flow
  • Generate JavaScript functions for each node that could run isomorphically
  • Provide a runtime that handled dependency resolution and recalculation

The result was that we could take an SME's spreadsheet and, with minimal effort, have it running as executable JavaScript. The frontend could use the same graph for real-time calculations as the user typed, and the backend could use it for validation and persistence. One source of truth, derived directly from the spreadsheet the SME understood.

// Conceptually, what GraphLib produced
const graph = {
  nodes: {
    'totalValue': {
      formula: (inputs) => inputs.propertyValue + inputs.landValue,
      dependencies: ['propertyValue', 'landValue']
    },
    'capRate': {
      formula: (inputs) => inputs.noi / inputs.totalValue,
      dependencies: ['noi', 'totalValue']
    },
    // ... hundreds more nodes
  },

  calculate(inputValues) {
    // Topologically sort and execute
    return this.topologicalExecute(inputValues);
  }
};

The Impact

What used to take weeks of careful translation work could now be done in days. More importantly, when the SME inevitably came back with "oh, we need to change how we calculate the debt service coverage ratio," we could update the spreadsheet and regenerate the graph. No more tracking down every place in the codebase where that calculation lived.

The frontend work became about UI/UX rather than business logic. We could focus on making the application actually usable - building intuitive interfaces, adding validation feedback, creating visualizations - instead of spending all our time making sure =(B15*C22)/SUM(D5:D50) worked exactly right.

Lessons Learned

Building GraphLib taught me a few things:

Respect the domain expert's tools

Spreadsheets aren't a bug - they're a feature. They're an incredibly powerful tool for domain experts to express complex business logic without needing to be programmers. Instead of fighting this, we should build bridges that let them continue working in their preferred environment while we extract the value for our applications.

Directed graphs are everywhere

Once you start seeing computation as graph execution, you see it everywhere. Build systems, reactive UI frameworks, data pipelines - they're all DAGs under the hood. Understanding this pattern deeply has been one of the most valuable mental models I've developed.

Automate the boring stuff

If you find yourself doing the same translation work repeatedly, stop and build a tool. The initial investment pays off exponentially, not just in time saved, but in consistency and reduced errors.

The Bigger Picture

Spreadsheets aren't going away. There will always be another SME with another Excel file that needs to become a web application. The question is whether we keep doing that translation manually, or whether we build systems that can bridge the gap automatically.

GraphLib was my answer to that question at Berkadia. It wasn't perfect - handling every Excel function, dealing with circular references, managing the edge cases of date formatting and currency handling - there was always more to do. But it transformed spreadsheet-to-webapp from a dreaded slog into a mostly mechanical process.

Death to spreadsheets? Not quite. But maybe: death to manually translating them, one formula at a time.