Well you might like Hyperscript or Elm, those are two approaches that work quite well using simple function calls.
The thing with JSX is introduces a syntax that is familiar to the rendered output (which is the status quo), and there's a relatively clear visual separation between the declarative and imperative parts; which is hard to enforce in pure JS.
I'm struggling to think what kind of control flow you're looking for when specifying a document consisting of a tree of components. If all you want is a way to render one nodeset over a different nodeset at runtime then you can easily do that by setting that behavior in the relevant component.
The thing with JSX is introduces a syntax that is familiar to the rendered output (which is the status quo), and there's a relatively clear visual separation between the declarative and imperative parts; which is hard to enforce in pure JS.