I think there's an art and technology to reusable components. This reifies "architecture" into something which can be slowly built up by the community as reusable tools. Lacking this technology one instead must fall to "frameworks" as the unit of shared community development.
This is directly related to one's ability to spin off a library containing a generalizable component of functionality and have it be repeatedly reused. My belief is that this is actually far harder than it ought to be in most languages. Actually, worse than that, most languages and the style of their libraries as supported by the community cause tradeoffs which penalize reusability quite harshly.
* It's difficult to manage documentation of interfaces
* Abstractions leak *heavily* and therefore have
exponentially complex "spooky interaction at a distance"
* Breaking algorithms into chunks must be done at
boundaries defined by efficiencies instead of as
defined by meaning (implementation privileged over spec)
Experienced Haskell users often talk about this story: that Haskell was the first language they ever used which actually felt reusable. This arose from the combination of powerful types, pure code, and laziness. The types provide clear, unbreakable interfaces between libraries. The purity ensures that libraries play together well and can be combined in more ways due to no "spooky interaction at a distance". The laziness ensures that when you cut sequences of computation into pieces you can recompose them later without losing efficiency.
I'm not going to claim that Haskell has figured out modularity, but I do think it's massively better than the status quo here. The upshot is that Cabal Hell is in part caused by the fact that nobody quite knows how to handle such massive modularity in practice.
Where that's relevant, I think, to this post is that without a genuine case for reusable modularity—supported at the language and the community levels—it is much harder to invest your time into reusable things and instead you focus efforts on frameworks. Lacking the technology to have legos we choose between prefab houses.
I think the best way for Javascript, i.e., to move forward away from framework driven development is to double down on the community's investment in purity as neither types nor laziness are ever going to be core to the language. This has already occurred in a small way with things like the virtual dom technique (which can be easily made immutable and updated purely) and the rise of things like Mori and Immutable.js.
As this pattern grows I predict the ability for people to genuinely build applications from well-cut, reusable components will become far more of a reality and the "framework epoch" will slowly close.