This post is based on personal side projects and does not reflect the views or practices of my employer.
Speed AND QualityWhy Most Engineers Pick One (And How to Stop)
I built a full-stack feature across three platforms in a single session. Backend API, mobile apps (iOS + Android), offline support, clean architecture, localization, and store-ready builds. No shortcuts. No tech debt.
This isn't a brag. It's a framework.
12 commits · 47 files · 3 platforms · 1 session
The AI Elephant in the Room
Let's address it upfront: AI can write code now. Copilot, Claude, Cursor — they'll generate a function, a component, an API endpoint in seconds. Code is becoming a commodity.
But here's what I've learned building products end-to-end: the bottleneck was never the code. It was always the decisions around the code.
- ▸Should I fix this at the data layer or the display layer?
- ▸ShouldI ship this now or wait until it's perfect?
- ▸Should I split this into five PRs or ship it as one?
AI writes code fast. But AI doesn't question the approach. AI doesn't think like the user. AI doesn't know when to stop implementing and start rethinking.
In the age of AI, the engineer who thinks clearly is more valuable than the engineer who types fast. The five principles below aren't about writing code — they're about making the decisions that determine whether the code matters.
“The bottleneck was never the code. It was always the decisions.”
Ship behind flags, not behind perfection
I built a feature that shows users where their content is being viewed — city, state, country. The geo-resolution was 65% accurate at city level. Someone in Pune showed up as Srinagar. That's embarrassingly wrong.
I shipped it anyway.
But I shipped it behind two feature flags. One controls whether users see the screen at all. The other controls whether city-level data is displayed or just country-level (which is 99% accurate).
The data accumulates silently in the background. When accuracy improves — better database, paid API, whatever — I flip a flag. No code change. No app update. No migration.
I've seen teams sit on features for weeks, polishing something nobody has used yet. And I've seen engineers ship broken things that erode user trust overnight.
Feature flags are the third option. Ship imperfect things safely. Learn from production. Control the blast radius.
The question isn't “is this perfect?” It's “can I control what happens if it's not?”
“Feature flags let you ship imperfect things safely.”
Think as the user, not the engineer
Same feature. I'm recording who views content. Each viewer gets a unique hash based on their device. Clean deduplication. Technically correct.
Then I actually tested it on a real phone. Viewed on WiFi — one viewer. Switched to mobile data — two viewers. Same person, same phone, counted twice.
An engineer sees this and thinks: “Two different IPs, two different hashes. The system is working correctly.”
A user sees this and thinks: “I'm one person. Why does it say two?”
The fix took 10 minutes once I saw it from the user's side. Send a persistent device ID instead of relying on IP. Done.
I catch more bugs by asking “what would the user expect?” than by writing test cases. Test cases verify assumptions. User thinking challenges them.
AI can generate perfect test suites for the logic. But it won't flag that the logic is solving the wrong problem. That requires empathy, not intelligence.
“I catch more bugs by asking ‘what would the user expect?’ than by writing test cases.”
Fix it right or don't fix it
I was working on a web project that had 20+ files of lint errors. The linting config was broken — a newer setup that never actually ran. Warnings accumulated silently for months.
When I fixed the config, every error surfaced at once. Unused imports, accessibility violations, unescaped entities, wrong HTML elements everywhere.
The temptation: suppress them. Add “warn” rules, keep moving. The build passes. Nobody notices.
I've watched people do this at every company I've been at. It always comes back.
Instead, I fixed every error across all 20 files. Removed dead code. Fixed accessibility. Proper components. Took about 30 minutes.
Suppressing warnings is borrowing time at 100% interest.
It always comes back. And it costs more at 2am on a Friday than it would have cost on a Tuesday morning.
AI makes this temptation worse, by the way. It's so easy to ask “suppress all these warnings” and get a clean build. But a clean build isn't clean code. And clean code is what lets me move fast tomorrow.
“Suppressing warnings is borrowing time at 100% interest.”
One session, one feature, end to end
Context is the most expensive thing in software engineering.
Not compute. Not salary. Not meetings. Context.
I learned this the hard way. When a feature gets split across five days, the mental model has to be rebuilt five times. “Where was I? What was that edge case? Why did I make that decision?” Each context reload costs 30-60 minutes. Over five days, that's 2.5-5 hours of pure waste — just re-understanding my own work.
That feature I mentioned? I built it in one sustained session. API endpoint, mobile data layer, offline queue with platform-specific retry, local cache, UI with animations, security rules, feature flags, localization, privacy policy. One session.
Not because I'm a masochist. Because splitting it would have cost MORE total time.
Monday: build the API. Tuesday: re-read Monday's code to build the mobile layer. Wednesday: re-read both to wire the UI. Friday: debug integration issues I would have caught instantly on Monday.
This isn't about working long hours. It's about reducing the tax on every hour.
A focused four-hour block beats four scattered one-hour blocks. Every single time.
“This isn't about working long hours. It's about reducing the tax on every hour.”
Question the approach, not just the code
Three times during that session, I stopped mid-implementation. Not because the code was wrong — because the approach was wrong.
First: I was fixing a privacy bug at the data sync layer. The code was clean, the logic correct. But the fix created a dependency that would break a future feature. Stopped. Moved the fix to the display layer instead.
Second: I was about to bundle a 180MB database into a serverless function. It compiled fine. Passed tests. Then it crashed in production — out of memory. The tool was wrong for the environment. Switched approach.
Third: I was building a separate class for recording analytics. Clean separation of concerns. But it meant two classes doing related things. Merged them into one. Single interface, single source of truth.
Each time, the code was fine. The approach was wrong.
This is where AI struggles the most. AI can write any implementation perfectly. But it won't stop and say “wait, should we even be doing it this way?”
That metacognition — the ability to debug one's own thinking — is the most valuable engineering skill of the next decade.
“The code is the easy part. The thinking is the job.”
The Evidence
Not because of heroics or caffeine. Because these five principles remove the friction that turns a one-day feature into a one-week feature:
The Anti-Patterns
These are patterns I've observed across teams over the years. Smart engineers, same mistakes:
“Let me just suppress this warning.”
That's not saving time. That's hiding a problem that will surprise someone at 2am.
“We'll refactor later.”
They never do. And now two people maintain code that one person should have written correctly.
“Let me split this into five PRs.”
That 5x's the context-switching cost. And the integration bugs that would have been obvious in one PR are now distributed across a week of reviews.
“It works on my machine.”
I've seen engineers who didn't test on a real device, didn't test with real data, didn't ask someone in another country to open the link. The gap between "works locally" and "works in production" is where engineering careers are made — or stalled.
The Bottom Line
In 2026, AI writes the code. The question is: who makes the decisions?
Speed and quality aren't a trade-off. They're a skill. And in the age of AI, they're the ONLY skill that matters — because everything else is being automated.
The fastest engineers I've worked with write the cleanest code. Not because they're geniuses, but because they've eliminated the things that slow everyone else down: indecision, rework, context loss, and the comfortable lie that “good enough” is good enough.
Ship behind flags. Think as the user. Fix it right. Stay in the zone. And question everything — especially my own approach.
The code is the easy part. The thinking is the job.

Mohammed Rampurawala
Software Engineer at Meta. Builds side projects to stay sharp and writes about the intersection of engineering craft and AI-augmented workflows.