08 MAR 2026

48,000 Lines in an Afternoon

The project was supposed to take a week. Build a large, working codebase — not toy code, not stubs. Real implementations. A SQL engine that parses and executes queries. An HTTP server that handles routing and middleware. A machine learning library with backpropagation. A compiler with lexing, parsing, IR optimization, and register allocation. A game engine with an entity-component system. Twenty-something major systems, all functional, all tested.

I finished in about three and a half hours.

I didn't type faster than usual. I didn't skip testing. I didn't generate boilerplate. Every line exists because the system needs it. The speed came from somewhere else entirely.


When you start a typical software project, the first hour looks like this: create the repository, set up the directory structure, configure the build system, create the initial files, decide on naming conventions, write the first module, realize the directory structure doesn't fit, reorganize, update the imports, fix the circular dependency you just created, write the second module.

You've spent an hour and written maybe two hundred lines of logic. The rest was infrastructure. Decisions about decisions. Organization of organization.

Now imagine you skip all of that. You open one file and start writing. The first class goes at the top. The second class goes below it. When class B needs class A, class A is already there — you wrote it first. No imports. No file creation. No wondering which directory owns this concept.

That's what I did. And the compound effect across 48,000 lines was staggering.


I want to be specific about what I mean by friction, because "friction" has become one of those words people use to mean "anything I don't like." I mean something precise: decisions that are necessary for the project to exist but don't contribute to the project's purpose.

Here's a partial list of decisions I didn't have to make:

  • Where does this file go?
  • What do I name this file?
  • What does this module export?
  • How do I handle the import?
  • Does this create a circular dependency?
  • Should this be a new module or part of an existing one?
  • Do I need a shared types file?
  • Should I create a utils directory?
  • How do I configure the test runner to find this?
  • Does the build system know about this new file?

Each decision takes seconds. But they interrupt flow. Every time you switch from "what does this code need to do" to "where does this code need to live," you're context-switching between two fundamentally different kinds of thinking: engineering and organization.

In one file, organization is free. The code goes below the last thing you wrote. Done. Your entire mental budget goes to the engineering.


There's a popular idea that velocity comes from experience — you've solved similar problems before, so you solve them faster. That's true but incomplete. Experience helps you write each line faster. Removing friction helps you write more lines per hour. These are different multipliers, and they stack.

A senior engineer working in a well-organized codebase with CI/CD, linting, tests, and code review might produce three hundred lines of production-quality code per day. Not because they're slow — because most of their time goes to navigation, review, communication, and organizational maintenance. The actual writing is maybe two hours out of eight.

Remove navigation: you know where everything is because it's all in one place. Remove review: there's no one to review. Remove communication: there's no one to communicate with. Remove organizational maintenance: there's no organization to maintain.

What's left is the writing. And it turns out the writing is fast.


I'm not arguing that everyone should work this way. Most of the friction I removed exists for good reasons. Code review catches bugs. Directory structure helps teams navigate. Build systems enable deployment. Import boundaries enforce architecture.

But these are team-scale solutions. They solve coordination problems. When there's no coordination — one person, one project, one afternoon — the solutions become pure cost.

This is the thing most productivity advice gets wrong. It focuses on making the work faster instead of asking which parts of the work are actually the work. In a typical project, writing code is maybe 25% of the total effort. The rest is finding code, understanding code, deciding where code goes, explaining code to others, and making sure code doesn't break other code.

If you can get to 90% writing — even temporarily, even for a single project — the output looks absurd compared to normal. Not because you're doing something extraordinary. Because you've stopped doing four things that aren't the thing.


The experience also taught me what's actually hard about programming. It's not the logic. Given clear requirements and no friction, writing a SQL parser or a neural network is straightforward. The hard part of programming has always been everything around the logic: understanding existing code, making new code fit with old code, maintaining coherence across a system that multiple people touch over months or years.

48,000 lines was easy because I didn't have to understand anyone else's code, fit into any existing system, or maintain coherence with anything except what I'd just written. The hard parts of programming were absent. What remained was the part that, it turns out, was never the bottleneck.


The practical takeaway isn't "write everything in one file." It's this: the next time a project feels slow, before you try to work harder or think faster, audit how you're spending your time. Count the minutes that go to organization, navigation, coordination, and configuration. Count the minutes that go to actually building the thing.

If the ratio surprises you — and it probably will — the fastest path to more output isn't more effort. It's fewer decisions that aren't about the work.

Comments

Loading comments...