Last month I set out to build a new product, and after a full week I had shipped exactly zero features.
Not because I was slow. Not because the work was hard. Because before anyone could write a single line of business logic, my team had to re-decide a dozen things our company should have settled years ago.
I’ve been a full-stack developer for almost five years — long enough to have worn most of the hats: WordPress developer, QA, frontend, backend, solution architect, founding engineer. I’ve built more than twenty web applications and a handful of mobile ones. Some of them I’m genuinely proud of: systems that poll PLCs every five seconds to watch over industrial equipment, a cybersecurity dashboard that mapped attacks across the world in real time using tree-based graphs, an OTT platform that streamed live events — including FIFA — to millions of concurrent viewers. Today I work on enterprise supply-chain finance software.
So when I tell you the hardest part of that new product had nothing to do with code, I know how it sounds. Let me explain.
The week that disappeared
The experiment was ambitious on purpose. I wanted to build the new application — eventually a microfrontend inside a larger enterprise platform — but I didn’t want to write most of it myself. I wanted Claude Code to implement while I acted as the architect: review, test, challenge, refine, repeat.
That part worked. The AI wasn’t the bottleneck. The bottleneck was everything that came before the first feature.
Should we use React? Vite? Keep Create React App because the parent app still runs it — or migrate both? How does the parent consume the child, and does local development still work? Does authentication still work? Does routing? Do we adopt TypeScript when the existing app doesn’t, knowing that splits one product into two standards? The app also had to feel native to the existing product — same spacing, typography, colors, interactions — except the company had a component library, not a design system, and those are not the same thing. A component library hands you buttons. A design system hands you consistency.
Then came setup: repositories, branch strategy, folder structure, ESLint, Prettier, Husky, commit hooks, Module Federation, auth integration, environment config, build scripts, shared packages, permission handling, boilerplate.
After almost a week, we still hadn’t written one piece of business logic. The customer had gained nothing. The product had gained nothing. We had simply prepared the ground — and even with AI helping the whole way, we’d burned thousands of tokens debating infrastructure instead of solving a customer problem. And we hadn’t yet touched CI/CD, monitoring, logging, deployment, or production.
Here’s the part that stings: almost every one of those decisions should have been made once, years ago, for the entire company. Instead, every new project re-litigates them from scratch.
That’s not a software engineering problem. It’s a platform engineering problem.
What “already solved” should feel like
Imagine joining a company where you create a repository — and that’s your entire setup task.
The framework is already chosen. TypeScript is mandatory and configured. Linting and formatting rules exist. Git hooks are installed. Testing is wired up. CI/CD pipelines, Docker images, and deployment workflows attach themselves. Monitoring, logging, and security scanning run by default. Secrets are managed, branch protection is on, code owners are set, and a preview environment spins up on its own. Local development starts with one command.
None of that is exotic. Every piece already exists as a solved problem somewhere in your organization. The failure is that it isn’t packaged — so each team rebuilds it, slightly differently, forever.
Two principles make the difference.
1. Standardize your technology, on purpose
There’s nothing wrong with supporting more than one stack — but support two or three, not ten. Draw a short, deliberate menu at every layer: Vite, React, or Angular on the frontend; Node, Spring Boot, or Python on the backend; a couple of blessed CI/CD paths, not one per team. Then choose from it by fit, not fashion — which of these do we already run, and which suits this project’s scale, audience, and speed? Answer that and the framework debate is over before it starts. A menu of three isn’t a cage; it’s permission to stop arguing and start building.
Draw the menu around the tools your engineers and DevOps already know best, document why each one made the cut, and stick to it. Every hour a team spends relitigating “React or Vue, Node or Spring” is an hour not spent on a feature — and every off-menu choice becomes tomorrow’s orphaned service that only one person can deploy. Narrowing the options doesn’t just save development time. It saves cost, and it’s the cheapest technical-debt insurance you’ll ever buy.
2. Own your interface, not just your components
Many teams proudly say “we have a component library.” Fine — but do developers import Ant Design, Material UI, or Bootstrap directly? If so, you don’t have a design system; you have shared dependencies. Every component should pass through your own abstraction layer so the third-party library underneath is replaceable and the experience never changes. Today it wraps Ant Design; tomorrow it wraps something else; your apps shouldn’t notice. Enforce it with linting, not with discipline — discipline doesn’t scale.
The same logic runs all the way down the stack. Databases, credentials, and secrets shouldn’t be a fresh negotiation at the start of every project; the platform should provision them and hand the app temporary credentials. Domains and SSL shouldn’t be a product engineer’s job — yet I’ve demoed products over insecure HTTP, and over raw AWS load-balancer URLs, because no one had provisioned a real domain yet. I’ve waited days for a valid HTTPS endpoint. None of that improved the product. It only delayed it. Requesting a new application should provision the domains, certificates, DNS, and load balancer before anyone clones the repo.
The one every engineer keeps rebuilding
If there’s a single anti-pattern I see most, it’s authentication. Every new app starts by rebuilding the same flows: login, logout, registration, password reset, email verification, JWTs, sessions, MFA, refresh tokens, RBAC, audit logs, user management. These problems were solved years ago. We solve them again anyway.
On one product, we stopped. We built an internal platform we call IIE — not a business product, an engineering one. Its whole job is to centralize what every application eventually needs: authentication, authorization, user management, approval workflows, notifications, audit trails, permissions, SSO. Instead of each product implementing all of that independently, apps integrate with IIE once. After that, a product team doesn’t think about identity at all. It thinks about the business problem.
That’s the real value of an internal platform: it removes undifferentiated effort, so every new application starts closer to the finish line because the hardest foundations already exist. Observability should work the same way — logging, metrics, tracing, health checks, error reporting, dashboards, and alerts present the moment a project is created, not something a developer has to remember to bolt on later.
The new wrinkle: AI needs onboarding too
There’s a fresh version of this problem, and it’s spreading fast.
I got banned from Stack Overflow once — years ago, for asking too many “obvious” questions. Back then, a stuck engineer walked to a senior’s desk, and if that failed, spent the night in the debugger. Today every one of those questions is one prompt away. The amount of accessible knowledge is genuinely astonishing.
But every engineer now runs a different AI stack — Claude Code, Cursor, Copilot, Gemini, ChatGPT, often several at once. Each agent knows something different. Each session loses context. Each engineer prompts differently, so each AI makes different architectural assumptions. Eventually the contradictions surface: duplicate implementations, hallucinated architecture, AI-generated spaghetti.
The answer isn’t banning AI. It’s giving AI context. Every project should carry Architecture Decision Records, living documentation, coding standards, explicit agent rules, and a shared glossary. Treat an AI agent like a new engineer joining the company. You wouldn’t let a new hire commit code before onboarding — so stop expecting AI to.
Why platforms are worth a whole team
People ask why a company should fund a platform team instead of shipping more features. Here’s the answer, in one line: a frontend engineer makes one team faster; a platform engineer makes every team faster.
That’s leverage — every project starts sooner, every deployment gets easier, every application grows more consistent, and every developer spends more hours on business logic instead of boilerplate. It’s one of the highest returns an engineering org can buy.
It isn’t free, and it isn’t always the right first move. A five-person startup that ships one product doesn’t need an internal developer platform; it needs customers, and a premature platform team there is just overhead building for imaginary scale. The calculus changes the moment you’re running several products and several teams in parallel — because that’s when you start paying the same setup cost over and over, and almost nobody measures it. Companies track story points, velocity, and bug counts. Very few track time-to-first-business-feature, time lost to repeated technical decisions, or time spent waiting on infrastructure and deployments. Those numbers are enormous, and they’re nearly invisible.
That invisibility is the whole trap. Writing code has gotten dramatically easier. Software engineering has not — because the bottleneck moved. It isn’t algorithms or syntax or frameworks anymore. It’s organizational engineering: the systems, standards, and foundations that decide how fast a good idea becomes a shipped feature.
The companies that build the best internal platforms won’t just have happier engineers. They’ll ship faster, with fewer bugs and more consistency — and their engineers will finally spend their time on what they were hired to do, instead of rebuilding the same foundation on every new project.
So a real question for the engineers reading this: at your company, how long does it take to go from “new product approved” to “first business feature merged”? A day? A week? A month? Drop the number in the comments — I want to see the range, because I suspect it’s worse than any of us admit.
Written by me, from my own experience. I used AI as an editor — to tighten structure and cut repetition — the same way I’d hand a draft to a colleague. The arguments, the war stories, and the platform we built are real.