On technology choices, and the humans who make them for you.
A Simple Observation
When you choose a framework, you believe you’re making a technical decision.
You’re evaluating features, performance, community support, documentation. You’re being rational. You’re choosing the best tool for the job.
But there’s something underneath that decision you rarely see.
Every framework is built by humans. Maintained by humans. Promoted by humans. Deprecated by humans.
And humans have motivations that extend beyond “what’s best for developers.”
This isn’t conspiracy. It’s just… how organizations work.
The Layers
What you evaluate:
The Technology
(features, syntax, performance)
What shapes the technology:
The Organization
(priorities, resources, direction)
What shapes the organization:
The Humans With Influence
(careers, ambitions, survival)A framework doesn’t exist in a vacuum. It exists within a structure of human decisions. And those decisions serve purposes you may never be told.
The Lifecycle
Technologies follow a pattern (Note: This is just one of the examples):
Birth: Someone with genuine insight creates something that solves a real problem. The motivation is often pure — they saw a need, they built a solution.
Growth: Success attracts resources. Teams form. The technology matures. This is usually the golden era.
Maturity: The original creators move on or lose influence. The technology is “done” — which means it’s no longer exciting. Maintenance isn’t glamorous.
Transition: New people need new projects. “New” is more visible than “maintained.” The existing technology becomes an obstacle to someone’s advancement.
Replacement: A new technology emerges. Not always because the old one failed — sometimes because the new one serves someone’s interests better.
This cycle isn’t evil. It’s just… organizational gravity. And it’s not unique to any one ecosystem — the same pattern appears in React’s ecosystem churn, Angular’s major-version breaks, Python 2 to 3, and countless others.
The Vocabulary
Pay attention to how technologies are described:
| Word | Surface Meaning | Possible Subtext |
|---|---|---|
| “Modern” | New, current | “The other thing is old, therefore bad” |
| “Legacy” | Old, existing | “We want you to stop using this” |
| “Best practice” | Recommended approach | “Our approach, not alternatives” |
| “Opinionated” | Has defaults | “Our opinions are built in” |
| “Cloud-native” | Works well in cloud | “Optimized for our cloud platform” |
Words are tools. They shape perception.
When a technology is called “legacy,” notice who benefits from that label.
The Migration Question
When a new technology replaces an old one, observe the migration path:
Smooth migration: The new thing respects your existing investment. Your code mostly works. Tools help you transition. There’s genuine care for your situation.
Rough migration: Significant rewrite required. Old patterns don’t translate. You must learn new ways. Your existing knowledge depreciates.
No migration: Complete rewrite. Old skills don’t transfer. Start over.
The nature of the migration path tells you something about priorities.
The Silence
Sometimes the most revealing signal is what isn’t said.
When an older technology stops being mentioned in official tutorials, documentation, and conference talks — even though millions still use it — that’s a choice.
Not updating documentation is a choice. Not presenting migration paths is a choice. Not acknowledging existing users is a choice.
Silence can be a strategy.
The Circle
Here’s a curious pattern:
Sometimes technologies evolve in circles:
Simple → Complex → More Complex → Simple AgainThe “new simple” often resembles the “old simple” — but with different names, different syntax, different ownership.
And the “old simple” is never credited.
This is natural in some of the human systems. New contributors need to own something. Acknowledging that the original approach was correct doesn’t build careers.
So: reinvention, renaming, reclaiming.
The Protection
If frameworks are shaped by human politics, how do you protect yourself?
Learn principles, not just platforms. HTTP is request/response. Data flows from storage to display. Users provide input, systems process it. These principles survive any framework.
Notice the narratives. When you believe something is “outdated” or “modern,” ask where that belief came from. Did you evaluate it yourself? Or did you absorb it from sources with their own interests?
Watch the actions. Beyond the words, observe: Is backward compatibility maintained? Are existing users respected? Is migration supported? Actions reveal priorities better than marketing.
Maintain optionality. Don’t lock yourself so deeply into any ecosystem that you can’t leave. The framework that’s promoted today may be “legacy” tomorrow — not because it stopped working, but because organizational priorities shifted.
The Compassion
Here’s the thing: the humans making these decisions aren’t villains.
The architect who promotes complexity? They’re protecting their role, their team, their mortgage payment.
The team that deprecates a working technology? They need new projects to justify their existence.
The speaker who declares something “legacy”? They need content that audiences will attend.
Everyone is surviving their own constraints.
The problem isn’t bad people. It’s systems that reward certain behaviors regardless of technical merit.
Consider how performance is measured:
KPI (or OKR) systems ask employees to set targets for the year. “Maintained critical system reliability” doesn’t fit well in those boxes. “Launched new framework” does. The KPI form teaches you what ambition is supposed to look like.
This pattern isn’t unique to any one company. Google engineers have openly discussed how promotion committees favor “launching something new” over “maintaining something that works.” The incentive structure is the same everywhere — only the specific technologies differ.
Appendix: A Timeline
Facts only. Conclusions left to the reader.
1996
- Classic ASP released
- Foundation pattern established:
Request("email")
Response.Write("Hello")- Direct HTTP access, no abstraction layer
- Mixed code and HTML (criticized for messiness, but foundation was sound)
- This pattern would survive for 25+ years
2002
- ASP.NET Web Forms released with .NET Framework 1.0
- Foundation inherited from Classic ASP:
Request["email"]
Response.Write("Hello")- Abstraction layer added on top:
- Server Controls, ViewState, PostBack
- Page Lifecycle, event-driven model
- The foundation remained accessible
- The abstraction became the marketed identity
2004
- Mono project achieves Web Forms compatibility
- Runs on Linux, macOS
- Demonstrates the foundation is not Windows-dependent
2008
- Mono’s Web Forms support matures
- XSP web server (pure C#), mod_mono for Apache, FastCGI for Nginx
- Community proves cross-platform is achievable
2009
- ASP.NET MVC 1.0 released
- Different architecture: Controllers, Actions, Views
- Different team from Web Forms
- Foundation still underneath:
Request["email"] // still works
Response.Write() // still works- No migration path from Web Forms to MVC
2014
- Microsoft acquires Xamarin (includes Mono)
- Mono team absorbed into Microsoft
2016
- .NET Core 1.0 released
- Marketed as cross-platform .NET
- Web Forms not included
- Official explanation cited architectural concerns: tight coupling to System.Web, stateful page lifecycle conflicting with modular, cloud-oriented goals
- Note: Mono had demonstrated cross-platform Web Forms for 12 years
2016-2020
- Web Forms documentation updates slow
- New tutorials default to MVC / .NET Core
- Term “legacy” appears in official contexts
2021
- .NET 6 introduces Minimal APIs
- Pattern returns to direct simplicity:
app.MapGet("/", (HttpRequest request) =>
Results.Ok(request.Query["email"]));- Request in, process, response out
- The 1996 pattern, new syntax
2023-Present
- Web Forms remains supported on .NET Framework 4.8
- No port to .NET Core / .NET 5+
- Millions of applications still running
The Pattern Exposed
The foundation lineage:
1996: Classic ASP → Request/Response (origin, visible)
2002: ASP.NET Web Forms → Request/Response (inherited, buried) + Server Controls (marketed)
2009: ASP.NET MVC → Request/Response (wrapped in controllers)
2016: .NET Core → Request/Response (wrapped in middleware)
2021: Minimal APIs → Request/Response (exposed again)25+ years. Same foundation. Different clothing.
Observable Facts
On the foundation:
- The Request/Response pattern predates Web Forms by 6 years
- Web Forms inherited it, kept it accessible, added abstraction on top
- Every subsequent framework still uses the same pattern underneath
On cross-platform capability:
- Mono ran Web Forms on Linux starting 2004
- Microsoft’s .NET Core excluded Web Forms in 2016
- The claim “too tied to Windows” contradicts 12 years of Mono evidence
On platform-specific technologies:
- Swift: iOS/macOS only, not labeled “legacy”
- Kotlin: Android primary, not labeled “legacy”
- Dart: Flutter/Google ecosystem, not labeled “legacy”
- Web Forms: Windows, labeled “legacy“
Platform-specificity is common across the industry. It is not inherently a disqualifying architectural flaw.
On migration paths:
- Classic ASP → Web Forms: Smooth (similar patterns)
- Web Forms → MVC: Complete rewrite required
- Web Forms → .NET Core: Not supported
- Web Forms → Blazor: Different paradigm entirely
On the cycle:
- 1996: Simple (Classic ASP foundation)
- 2002: Abstraction added (Server Controls)
- 2009: New complexity (MVC)
- 2016: More complexity (.NET Core ceremony)
- 2021: Simple again (Minimal APIs)
The journey returned to where it started.
End of appendix.
Understanding this doesn’t require anger. It just requires seeing clearly.
The Invitation
Next time you choose a technology, or hear that something is “outdated,” or watch a conference talk about “the modern way” — pause.
Ask:
- Who built this? What were they trying to achieve?
- Who promotes this? What do they gain?
- Who deprecated the alternative? What did they gain?
- What would I conclude if I evaluated this myself, without the narratives?
You may reach the same conclusions. The popular choice may genuinely be best for you.
But you’ll reach those conclusions with open eyes.
And that’s the difference between choosing and being chosen for.
Closing
Technology feels objective. Code either works or it doesn’t. Performance can be measured. Features can be listed.
But the decisions about technology — what gets built, what gets promoted, what gets deprecated — these are human decisions. Made by humans in organizations, with human motivations.
This isn’t cynicism. It’s just clarity.
The technology serves you best when you see it clearly — including the invisible hands that shaped it.
The best tool for the job is the one you chose — not the one that was chosen for you.
