D3 is definitely a library, though not a framework. There are conventions, but there are also magical abstractions that work together like selections, data-binding and transitions. I would not call the eight lines of code you need to write for a basic visualization and transition "low-level".
Composability is achieved with configurable functions. Is there an alternate solution you propose? What helper would be useful for data that changes over time?