I'm currently working on a Next.js project (for my sins). This project has a pretty extensive backend. Unfortunately, said backend is a nest of middleware and implicit argument passing. Pretty much all functionality has been implemented by means of saving things to a request object, and then reading them later.
This is, of course, completely incomprehensible, isn't type-checked, and breaks all the time because the scope of any change is unclear. I spend a lot of time trying to unpick existing work, to get into a position where a simple change can be made.
Here are my current key principles for writing maintainable software