
For most of my career I thought shipping faster meant writing faster.
So I optimized for output. Faster typing, more snippets, longer hours. And somehow the more code I produced, the slower the project felt. Every feature I added made the next one harder. Every line was a line someone had to read, test, debug, and maintain forever.
The breakthrough came when I started measuring myself by the wrong-feeling metric: how little code I could write to solve the problem. My velocity didn't drop. It roughly doubled.
You ship faster by writing less code because every line you write is a liability you maintain forever. The unlocks are deleting code that doesn't earn its place, reusing what already exists instead of rebuilding it, and saying no to features and abstractions you don't need yet. Less code means fewer bugs, faster reviews, and less to maintain — which is what actually slows teams down.
This reframe changed everything for me.
We talk about code like it's wealth — "lines of code," "productivity." But every line you write is something you now owe. It has to be read, understood, tested, secured, and maintained until the day it's deleted. The asset is the problem solved. The code is the debt you took on to solve it.
Once I started seeing code as a cost, the cheapest solution was obviously the one with the least of it. A feature I could deliver in fifty lines was strictly better than the same feature in five hundred, because future-me had ten times less to carry. This restraint is one of the quiet markers of the shift from junior to senior engineering — knowing what not to write matters as much as knowing what to.
Your job isn't to produce code. It's to solve problems while accumulating as little code as possible.
Photo by Ilya Pavlov on Unsplash
My most productive afternoons now sometimes end with a negative line count.
I went looking for code we no longer needed: dead feature flags, abandoned endpoints, a whole "flexible" config system built for a use case that never came. Deleting it didn't just clean things up. It made the next feature faster, because there was less surface area to work around and less to break.
Some of the highest-leverage moves are subtractive:
Deleting code feels unproductive because the line count goes down. It's one of the most productive things you can do.
The fastest code to write is the code you don't write because it already exists.
I used to rebuild things from scratch out of pride or habit — a date helper here, a retry wrapper there. Now my first move on any task is to look for what already solves it: an existing function in our codebase, a battle-tested library, a developer tool that does the job. Borrowing a solved, tested solution beats writing a fresh, buggy one almost every time.
The honest trade-off table I keep in mind:
| Rebuild from scratch | Reuse what exists |
|---|---|
| Full control, full bugs | Battle-tested edge cases |
| Slow to write | Fast to wire up |
| You maintain it forever | Someone else maintains it |
| Fun, occasionally | Boring, usually right |
There's a balance — I'm not pulling in a giant dependency to avoid a three-line function. But for anything non-trivial, the reused, hardened solution wins on speed and on the maintenance bill.
Photo by Annie Spratt on Unsplash
Saying no is the most powerful speed tool I have.
Every feature request arrives wrapped in urgency. But a lot of them, gently questioned, turn out to be solving a problem that barely exists, or one a tiny tweak to an existing feature could handle. The feature I talk the team out of building is a feature with zero bugs, zero maintenance, and zero review time. It ships instantly, by not existing.
This applies to internal complexity too. The "what if we need this later" abstraction. The configurable system for a single use case. The generic framework for two examples. Saying no to speculative flexibility keeps the codebase small and fast to change — and you can always add the abstraction the day a third real use case actually shows up.
I let a little automation enforce my "no" — boilerplate and scaffolding get generated rather than hand-written, so the only code I'm personally responsible for is the part that's genuinely unique to the problem.
The compounding payoff shows up in the whole team's speed.
Smaller changes get reviewed faster and more carefully — a fifty-line PR gets real scrutiny, a five-hundred-line one gets a rubber stamp and three hidden bugs. That tighter review loop is exactly the dynamic behind the code review rule that changed my team. Less code means a smaller surface for bugs to live in. Less code means new teammates understand the system faster — a point Google's web.dev guidance keeps returning to when it talks about shipping leaner, more maintainable front ends. Every one of those is recovered time.
When I added up where my "slow" projects had actually lost time, almost none of it was in the typing. It was in reviewing bloated changes, debugging unnecessary complexity, and maintaining code that never needed to exist. Writing less attacked all of it at once.
Here's a concrete week that made the principle click for the whole team.
We had a feature request that, as written, was going to be a big build — a configurable rules engine so account managers could set up custom workflows. The estimate was three weeks. I sat with the person who asked for it and walked through what they actually did all day. It turned out they needed exactly two workflows, both of which we could express with a single setting and ten lines of code. The "engine" was solving a generality nobody had asked for.
We shipped the ten lines in an afternoon. Three weeks of work evaporated into half a day, and the user got what they needed sooner. That's not a productivity hack. That's just refusing to build the thing nobody needed.
The same week, I went through an old module and deleted a "plugin system" a previous engineer had built for extensibility that never materialized. Three files, gone. The next feature in that area got noticeably easier because there was no speculative machinery to thread through anymore.
| Where the time went | The "less code" move |
|---|---|
| 3-week rules engine | 10 lines, shipped same day |
| Unused plugin system | Deleted three files |
| Custom date utility | Reused an existing library |
| "Flexible" config layer | Cut it; added it back never |
Add those up and the week's headline accomplishment was a sharply smaller codebase that did more of what users actually wanted. On a lines-of-code dashboard, it looked like I'd gone backwards. In reality it was one of the most productive weeks I'd had — precisely because so little of it survived as code.
The lesson stuck because it was so visible. I'd spent years equating progress with accumulation, and that one week showed me the opposite was usually truer. The most senior-feeling thing I did all month was talk a three-week project down to an afternoon, and nobody would ever see it in a metric.
None of this works as a set of tricks. It only works as a change in what you think your job is.
If you believe your job is to produce code, then deleting, reusing, and saying no will always feel like failing at your job. You'll feel a quiet guilt every time you ship less. That guilt is the thing to root out, because it's pushing you toward the bloat.
The reframe is simple but it takes a while to internalize: your job is to solve problems for people while accumulating the least possible liability. Code is one way to solve a problem, and it's the expensive way, because you own it forever. Every time you solve a problem without adding code — by reusing, by simplifying, by talking it out of existence — you've done the job better, not worse.
Measure yourself by problems solved and liability avoided, not by lines produced. The whole thing falls into place from there.
Once that clicked for me, writing less code stopped feeling like restraint and started feeling like skill. And the projects that used to drag through wet concrete started moving again, because there was simply less of them to move.
If you want more field notes like this on building leverage instead of bulk, it's worth following along and trying the "delete first" habit on your own codebase this week.
Q: Doesn't writing less code mean cramming everything into clever one-liners? No — that's the opposite of the goal. Clever, dense code is harder to maintain. The aim is fewer lines because the problem is genuinely smaller, the solution is reused, or the feature was cut — while the code that remains stays obvious.
Q: When should I rebuild instead of reuse? Reuse unless the existing solution is a poor fit, unmaintained, or so heavy that pulling it in costs more than it saves. For trivial logic, a few clear lines of your own can beat a dependency. For anything with real edge cases, reuse.
Q: How do I say no to features without seeming unhelpful? Don't reject — question. Ask what problem the feature solves and for whom. Often that conversation reveals a simpler answer, and you've helped more by saving the work than by doing it.
Q: Isn't deleting code risky? Less risky than keeping dead code around. Delete with tests and version control as your safety net. Unused code that quietly rots is the real risk — it confuses readers and hides bugs.
I got faster the moment I stopped treating code as output and started treating it as debt. Delete what doesn't earn its place. Reuse what's already solved. Say no to what you don't need yet. The code you never write is the code that never breaks.
The best engineers I know aren't measured by how much they write. They're measured by how little they had to.
What's one thing in your codebase you could delete this week and feel lighter for it?
I spent years saving the hardest task for when I 'felt ready.' Doing it first instead quietly fixed my focus, my dread, and my output.

I tracked every distraction for a week and was horrified by what I found. Then I fixed the three that mattered most.

No following, no network, no luck. Just an unglamorous system I ran for eighteen months. Here's exactly what I did.

Comments
Sign in to join the conversation
No comments yet. Be the first to share your thoughts!