Make it work make it right make it fast: Why Kent Beck’s Mantra is Still the Best Way to Code

Make it work make it right make it fast: Why Kent Beck’s Mantra is Still the Best Way to Code

You've probably been there. You're staring at a blank IDE, the cursor blinking like a heartbeat, and you have no idea how to start. The pressure to write "clean code" is paralyzing. You want it to be elegant. You want it to be scalable. But honestly? You just need the damn thing to run. This is exactly where the philosophy of make it work make it right make it fast saves your sanity.

Kent Beck, the creator of Extreme Programming and a co-author of the Agile Manifesto, coined this phrase decades ago. It wasn't just a catchy slogan for a bumper sticker. It was a direct attack on the "Big Design Up Front" culture that used to suffocate software engineering. It’s about momentum. It’s about the reality that you cannot optimize something that doesn't exist yet.

Stop overthinking the first draft

The first step is simple: make it work.

This is the "ugly" phase. It’s the part where you write code that would make a senior architect weep. You’re using global variables where you shouldn't. You’re hard-coding strings. You’re probably ignoring every SOLID principle ever written. And that is perfectly okay.

Why? Because the hardest part of any technical task is overcoming the "cold start" problem. When you focus solely on making it work, you’re exploring the problem space. You’re discovering the edge cases you didn't think of during the planning phase. If you try to build a perfectly decoupled microservice architecture before you even know if your logic handles a null pointer correctly, you’re just building a very expensive house of cards.

Think about the early days of any major tech product. Twitter (now X) famously struggled with its "Fail Whale" because the original Ruby on Rails implementation couldn't handle the massive surge in traffic. They started by making it work. They didn't start with a globally distributed, high-throughput Scala backend. They started with a basic CRUD app because they needed to see if people even wanted to tweet.

The trap of premature optimization

Donald Knuth famously said that premature optimization is the root of all evil. He wasn't kidding. When you skip the "make it work" phase and jump straight to "make it fast," you end up optimizing code that might not even need to exist. You waste hours shaving milliseconds off a function that only runs once a week.

It’s a massive ego trap. We want to feel like geniuses. We want our GitHub commits to look like poetry. But business doesn't care about poetry; it cares about solved problems. If you can’t get the prototype to function, the "rightness" of the code is a moot point.

Refactoring is where the magic happens

Once the feature is running, you move to the second stage: make it right.

This is where you pay back your technical debt. Now that you understand the problem—because you’ve actually solved it once—you can see the patterns. You see where the logic is repetitive. You see where a Class is doing too much. This is the moment to apply design patterns, improve readability, and write your unit tests.

"Making it right" is about maintainability. If you leave code in the "make it work" state, you’re creating a nightmare for your future self. Six months from now, you won't remember why you used that weird hack. Refactoring is an act of empathy for the person who has to read your code later, which, let's be honest, is usually you.

In his book Refactoring, Martin Fowler emphasizes that you shouldn't be adding new functionality during this phase. You are strictly changing the internal structure without changing the external behavior. It’s a disciplined process. You move a method. You run the tests. You rename a variable. You run the tests.

Why "Right" comes before "Fast"

There’s a very specific reason why "make it right" precedes "make it fast." Correct code is easier to profile. If your code is a tangled mess of "spaghetti," identifying the actual bottleneck is nearly impossible. When you have clean, modular code, you can easily drop a profiler on it and see exactly which function is eating up all the CPU cycles.

🔗 Read more: How do you pay Verizon bill from phone? The fastest ways to get it done today

Clean code is also safer to optimize. Optimization often involves making code more complex or less readable for the sake of performance (like using bitwise operators or unrolling loops). If the underlying logic is already solid and well-tested, you have a safety net. You can tweak the performance knowing that if you break the logic, your tests will catch it immediately.

The final frontier of performance

Now, and only now, do you make it fast.

Most developers spend way too much time here. In reality, about 90% of your code doesn't need to be "fast." It just needs to be "fast enough." If a user is waiting for a page to load, a 200ms delay is imperceptible. Spending three days to get it down to 50ms is a waste of company resources.

However, when you do hit a genuine bottleneck—like a database query that hangs for five seconds or a data processing script that takes all night—that's when you optimize.

True optimization involves data, not guesses. Use tools. Chrome DevTools for the frontend. pprof for Go. Your favorite APM for the backend. Look for the "long poles in the tent." Often, the fix isn't some high-level algorithmic change. It’s usually something boring, like adding a missing index to a SQL table or realizing you’re calling an API inside a loop.

Real-world speed: The Google example

Google is obsessed with speed, but even they follow this flow. When they develop a new feature, they don't always launch with the most optimized version. They launch, they gather telemetry, and then they optimize the parts that users actually interact with the most.

Speed is a feature, but it’s a feature that costs a lot of engineering time. By delaying the "make it fast" phase, you ensure that you're only spending that expensive time on the code that truly matters.

The psychological shift of the mantra

Using make it work make it right make it fast changes how you feel about your work. It removes the "perfectionist's block."

It gives you permission to be mediocre for an hour so you can be great by the end of the day. It’s a recursive loop. You apply it to a small function. Then you apply it to a whole module. Eventually, you apply it to your entire career path.

Many people fail because they try to do all three at once. They want the first line of code to be the fastest, most correct line ever written. That’s not how human brains work. We learn by doing, failing, and iterating.

Common misconceptions

A lot of people think "make it work" is an excuse for shipping garbage. It isn't. It’s a development strategy, not a shipping strategy. You should rarely ship something that is only in the "make it work" phase unless you're in a "hair on fire" emergency.

Another misconception is that you have to do these in a perfectly linear order for every single task. Sometimes, if you’re doing something you’ve done a thousand times before—like setting up a standard API endpoint—you can "make it work" and "make it right" almost simultaneously. But for anything novel or complex, sticking to the stages is a lifesaver.

How to actually implement this tomorrow

If you want to start using this approach, you have to change your workflow.

  1. The Sketch Phase: Open a scratch file. Write the logic in pseudo-code or the messiest version of your language. Get the output you want. Don't worry about folders or architecture. Just get the print statement to show the right result.
  2. The Cleanup: Move that logic into your actual project. Create the necessary classes or functions. Give them descriptive names. Add comments explaining the "why" behind the "how." Write a test that proves it works.
  3. The Audit: Run the code. Is it slow? Does it feel laggy? If no, stop. You’re done. Move to the next task. If yes, fire up a profiler. Find the one specific spot that is slow and fix only that.

The value of knowing when to stop

The most important part of this whole philosophy is knowing when to walk away. Software is never "finished"; it’s only "shipped." There is always a cleaner way to write it. There is always a faster way to run it.

The make it work make it right make it fast framework provides a natural stopping point. If it works, and it’s right (maintainable and tested), and it’s fast (meets your performance SLAs), then you are done. Anything more is just over-engineering.

Actionable insights for your next sprint

  • Set a timer for "Make it Work": Give yourself 30 minutes to get a "broken" but functional prototype. No refactoring allowed until the timer goes off.
  • Audit your "Right": Look at your last three PRs. Did you skip the "make it right" step because of a deadline? Go back and spend one hour cleaning up the messiest part of that code.
  • Measure before you "Fast": Never optimize based on a "hunch." If you can't show a graph or a log proving it's slow, don't touch the performance.
  • Embrace the mess: Accept that your first draft will be bad. Professional writers know this. Professional athletes know this. It’s time developers accepted it too.

The beauty of this approach is that it scales. Whether you are building a small hobby project or a massive enterprise system, the path remains the same. You solve the problem, you clean the solution, and then you tune the engine. Anything else is just making life harder than it needs to be.