I tend to use more of the bottom to top design philosophy in software.
It is hard to know exactly what the final product should look like, so instead I try to build small, independent, reusable parts.
That way, whatever interface we end up wanting in the future, we can have it built right away by composing the parts we need.
For example, this headers module
https://github.com/zack-bitcoin/light-node-amoveo/blob/master/src/js/headers.jsit only depends on the module for the hash function, and a module for big integers.
It can be easily reused in any other javascript code we could want.
Almost all the modules are like this.
I am writing in vanilla JS, so we don't depend on any external libraries that could get depreciated, and it is compatible with all browsers.