I started working on a Vue project that needed to add a couple visualizations, and initially I didn't overcomplicate, and did it just with d3 and "DOM manipulation". Later on I also tried this approach because it's what Vue expects and otherwise has quirks if you don't use its templating, but in the end stayed with d3 because some things seemed just really simpler (e.g. transitions). The complexity doesn't really change if you go from .append('circle').attr('r'...) to <circle r="... />. It's definitely from a previous era, and feels a bit dated, but this also has its advantages. For example, SVGs don't have z-index, and so it's done by the order of the children nodes. With a template you would have to copy a large chunk of code and paste it somewhere else if you want to change the order, but with d3 it could be a one line change (e.g. take this .append('g') and move it below that .append('g')).<p>But either way, the real value in d3 are all the layouting functions, where you dump in your data, and it gives you a path to draw. How you then draw this data is really less important.