"Standardization is boring."
I've heard this phrase more times than I can count. Usually from senior engineers who've been burned by "one-size-fits-all" solutions. Usually right before they propose building Yet Another Custom Framework™.
But here's the thing about boring: it scales. And after migrating 5 legacy PHP frontends to our standard Node pipeline, I've become a born-again convert to the church of "boring technology."
Let me tell you why.
The Mess We Inherited
Our product had grown organically over 7 years. Different teams, different eras, different opinions about what "good" looked like.
We had:
Legacy PHP monolith (custom framework, no tests)
PHP + jQuery (circa 2014, with "creative" use of global variables)
PHP + AngularJS (the 1.x version, because why not?)
PHP + Vue 2 (our "modern" one, but with Webpack configs from hell)
PHP + vanilla JS (a "micro-frontend" before that was a word)
Each had its own:
Deployment process (some FTP, some Jenkins, one was literally a bash script that scp'd files)
Dependency management (Composer? NPM? Just commit the vendor folder?)
Environment variables (.env, .env.local, .env.production, and one that used a JSON file in S3)
Build process (or none at all)
Testing strategy (or none at all)
Onboarding a new developer took 1 week. Minimum.
And that was assuming they already knew PHP. If they were a Node/React hire? Good luck. We'd lose them in the first 3 days, buried in a forest of php.ini configuration and mysterious 500 errors.
The Migration: Boring Choices, Big Impact
I didn't propose rewriting everything in Rust with WebAssembly. I didn't propose a microservices architecture with Kubernetes and service meshes.
I proposed: "What if we just... used our standard Node pipeline?"
The stack:
Node.js + Express (API layer)
React (frontend, with Vite)
TypeScript (because we like our sanity)
Standardized deployment (GitHub Actions → Docker → ECS)
Shared ESLint/Prettier configs
Same testing tools (Jest + React Testing Library)
Same logging/monitoring (Datadog, structured JSON logs)
Nothing innovative. Nothing that would get a conference talk. Nothing that made me feel like a 10x engineer.
But here's what happened:
Migration 1: The Monolith
Took 3 weeks. We had to extract business logic, build a proper API, and reimplement feature flags. Painful, but we now had API contracts.
Migration 2: jQuery Era
Took 2 weeks. Mostly just rebuilding components in React. The API was already there from migration 1.
Migration 3: AngularJS
Took 1 week. Similar patterns, easier because React is... well, React.
Migration 4: Vue 2
Took 4 days. The patterns were close enough that we could map components 1:1.
Migration 5: Vanilla JS
Took 3 days. Minimal state management meant minimal migration effort.
Total: ~6 weeks of focused work.
The Real Win: Onboarding Time
Before migration: 1 week to get a new dev productive.
After migration: 1 day.
Here's what that day looks like now:
Hour 1: Clone repo, run npm install, run npm run dev. Application is running locally. No php.ini tweaks. No Xdebug setup. No "but it works on my machine."
Hour 2: Walk through our standard dev setup: how to run tests (npm test), how to lint (npm run lint), how to build (npm run build). Same commands as our 8 other microservices.
Hour 3: PR is opened for a small bug fix. CI passes (because the same CI runs on every repo). Reviewer comments on style (and they're using the same ESLint rules, so most style issues are already caught).
Hour 4: First deployment. Same GitHub Actions workflow. Same ECS task definition. Same Datadog dashboards.
Day 2: They're picking up tickets independently.
The Unsexy Metrics That Matter
Metric Before After
New dev onboarding time 5-7 days 1 day
Setup errors ~3 per new dev 0
Time to first PR 4 days 3 hours
Deployment failures ~15% ~2%
Context switching 5 different mental models 1 mental model
"Where is X configured?" questions Daily Never
Why This Matters (Beyond the Numbers)
Here's what I learned from this migration:
Innovation is expensive
Every bespoke solution is a tax on future developers. Choose to be boring when it matters.Boring scales, exciting doesn't
Your team doesn't need to be impressed by your tech stack. They need to ship features and go home at 5 PM.Onboarding is a signal
If it takes 1 week to get someone productive, that's not a problem with your new hires. That's a problem with your architecture.Consistency compounds
Once everything uses the same patterns, you stop thinking about the tooling. You start thinking about the product. That's the real win.The best migration is the one you finish
Did we make perfect choices? No. Did we rewrite everything in the "optimal" way? No. Did we finish? Yes. That matters more than perfection.
What We Lost (and Didn't Miss)
Lost: The freedom to choose the "right tool for the job" on a per-project basis.
Didn't miss: The freedom to choose the "right tool for the job" on a per-project basis.
Lost: Engineers feeling clever because they used a niche framework.
Didn't miss: Engineers feeling clever because they used a niche framework.
Lost: The ability to optimize every frontend independently.
Didn't miss: Debugging 5 different deployment failures on a Friday afternoon.
The One Problem We Still Have
Recruiting. Because when I describe our stack to candidates, it's not exciting.
"React? Node? TypeScript? You're like every other company."
Yes. Exactly.
But you know what else I tell them?
"Your first day, you'll write code that ships to production. Your second day, you'll pick up a ticket. Your third day, you'll be teaching the intern."
That is exciting.
Practical Takeaways
If you're considering a similar migration:
Start with API extraction. Separate data from presentation before you touch the frontend.
Standardize deployment first. If you can deploy anything the same way, migrations get easier.
Accept temporary duplication. During migration, we had both PHP and Node running in production. Traffic was split. It worked.
Don't rewrite business logic. If you can, keep the domain logic intact and just change the presentation layer.
Move fast on migrations. The longer a migration takes, the less likely you are to finish. 6 weeks was intense, but it was finished.
Celebrate the boring wins. When a new dev ships on day 1, call it out. That's the metric that matters.
The Bottom Line
Standardization isn't exciting. It won't get you on the front page of Hacker News. It won't get you a speaking slot at your local tech conference.
But it will:
Get new devs shipping code on day 1
Reduce production incidents
Make debugging easier
Let your team focus on product, not tooling
Ship features faster
And honestly? That's way more interesting than arguing about frameworks.
Have you standardized your stack? What was the biggest win (or pain point)? Drop a comment below—I'd love to hear your war stories.
P.S. If you're on a team where "boring" is considered a bad word, send this article to your tech lead. Sometimes the most impactful engineering work is the stuff that's invisible when it's done right.
Top comments (0)