Changing old code is risky

Published by Beto Dealmeida on

A reflection on old code

I was talking to a colleague today who's a junior engineer. He was refactoring some code that my team wrote in the last few weeks, trying to improve type conversion when passing objects between the frontend and the backend. On the frontend, an object is being serialized to a string via JSON.stringify. The resulting string is then appended to another object, which also gets serialized to a JSON string in the request payload.

My recommendation was to remove the call to JSON.stringy in the frontend, remove the probable call to json.loads on the backend, reducing the amount of code and simplifying the mental load. He started doing that, but then realized that we are doing the same double-serialization before our changes, in parts of the API that already existed. I said:

Don't change it, then. The older the code is the more risky it is to change it.

I was surprised by what I said. Almost every engineer loves refactoring code, rewriting projects from scratch and getting rid of old code. I know I do. Old code doesn't follow the latest best practices. It doesn't use the new testing libraries. It doesn't leverage new features from the programming language — no async, no TypedDict. It's easy to dismiss it as inelegant and stale.

But old code has a history. It survived bugs, fixed them, worked around them. It's also harder to understand. When you revisit old code it's harder to understand the context, the subtleties, the reasoning — even with good comments left behind. Dismissing the old code is both disrespectful and unwise.