And sometimes they invent a framework that hits all the right design points, but junior engineers can't read a book about them or take a class about them, so don't understand and badmouth them as crappy and a result of boredom or ego.
Its hard to invent something, and have it get no traction because nobody else wants to move forward.
I've been at two startups that had frameworks that solved all the problems in the product space, efficiently and nearly perfectly. And failed because as the company grew, new Engineers all clamored for something simpler or something they already knew. They outnumbered the designer with their voices and management steered the company off the rails. It's tragic.
This is an incentive alignment problem. Developers want to maximize their human capital since they usually don't have significant capital in the business itself. With experience in all the latest buzzword technologies, they can get good offers elsewhere, or use the leverage to increase their pay. Whereas sinking all their effort into an in-house framework is fantastic for the business in multiple dimensions: it's a custom fit so it's more productive, but it also locks in the employees, reducing their employability elsewhere and BATNA.
I do wonder if incentives can be aligned for things like this, or if it's just a structural problem we need to live with.
I think that's orthogonal. You can fall behind just as easily by not addressing technical debt. Consider how easily it is, particularly in the JS world, to accrue multiple different bits of UI written in different frameworks du jour.
Rewriting stuff is very seldom in the business' interest, but stuff gets out of date at a rate controlled by the ecosystem, not the company.
Generally speaking, the worst kind of legacy code is the kind that cannot be easily rewritten. That's why I particularly called out custom frameworks and custom languages. Replacing custom service implementations, in comparison, doesn't even count as "replacing stuff" since it's so trivial.
It's not in the company's best interest, generally, to write business-critical things in ways that are hard to replace and/or pivot on. This means that a company needs to account for the whims of "the ecosystem" in both its business plan and in its technical strategy. If it's a huge concern, the profit margins need to stay high enough and customer expectations need to stay flexible enough to mitigate the concern. Also, if "the ecosystem" is a huge concern, technical strategies also need to help mitigate. For example, if you're running the same JS code both client and server side and you're worried about changes in the client-side ecosystem, you might want to think about implementing the backend in something more boring and stable just to mitigate ecosystem risk.
The code that you can't afford to rewrite is the code that is hairy with details. The details are some mix of essential and incidental complexity. The ratio is dependent on the degree of fit between your business logic and the framework, the primitives it's built out of, whether it's third-party, custom framework, custom language, whatever. And of course any custom component has its own complexity; it should be additive, but it may still be large. A good fit - an excellent fit - means your business logic is clear, concise, and is operating over abstractions that map directly to the business concepts. A poor fit is speaking haltingly in unidiomatic language, too verbose, aggregating globs of ugly code, losing track of the forest for the trees, etc. But it'll be easier to find average devs who are familiar with the particular style of thicket that ends up coming out. We even have names for the scar tissues that grow around each glob, helping them interface - we call them design patterns.
There's no hard and fast rules, it seems to me. Use a small fraction of lots of different third party bits and pieces and you get a recipe for pain. I'm fairly certain there's no more productive way for engineers to code than to raise the level of their language into their business domain - http://www.paulgraham.com/progbot.html - but this is the custom framework / language approach. I'm also fairly sure that it's hard to scale an organization around this approach because of the incentive problem when hiring developers. I think it only really works for startups that are composed of a bunch of hackers with decent equity stakes. It doesn't work out for employees, unless the company ends up moving the needle industry wide, like Java or Rust or React, and that's really rare, too rare to bet on.
Well, my thought is that, on average, learning people have less organizational impact than experienced people, both in a positive and a negative direction. You get the risk more concentrated in super-senior engineers. Hiring a dozen net-uninformed college grads would do the trick, too, though.
Its the medium-experience Engineers that pose the risk then, of having enough knowledge to talk, but not enough experience to appreciate the fine points of what they're talking about. They fool management with plausible but wrong arguments. In my experience anyway.
And today, the demographic may be skewed toward just that group.
Its hard to invent something, and have it get no traction because nobody else wants to move forward.
I've been at two startups that had frameworks that solved all the problems in the product space, efficiently and nearly perfectly. And failed because as the company grew, new Engineers all clamored for something simpler or something they already knew. They outnumbered the designer with their voices and management steered the company off the rails. It's tragic.