Make it work, Make it right, Make it Fast
Make it work, Make it right, Make it Fast

Make it work, Make it right, Make it Fast

We have all been there. You open your IDE, stare at the blinking cursor, and the anxiety kicks in.

"Is this for loop going to be too slow?" "Should I use a Class here or just a factory function?" "Is this architecture scalable enough for a million users?"

The result? You haven't written a single line of code, yet you are already stuck. This is classic analysis paralysis.

To break out of this trap, there is a legendary mantra in software engineering, often attributed to Kent Beck: Make it work, Make it right, Make it fast.

In the world of JavaScript, where flexibility is king (and often a trap), this principle is your best friend. Let's break it down.


1. Make it work

This is the discovery and draft phase. Your one and only goal here is to solve the functional problem. Forget about elegance. Forget about performance. Forget about "Clean Code."

If you need to copy-paste a snippet from StackOverflow to test a hypothesis, do it. If you need to write a 50-line function with nested if statements, go for it.

The JS Example: Let's say you need to filter a list of users to find adults and format their names.

It's ugly, but it works.test.js
JavaScript
// Phase 1 : C'est moche, mais ça marche.
function processUsers(users) {
  let results = [];
  for (let i = 0; i < users.length; i++) {
    if (users[i].age >= 18) {
      let fullName = users[i].firstName + " " + users[i].lastName;
      results.push(fullName.toUpperCase());
    }
  }
  return results;
}

This code is imperative, verbose, and "old school." But it fulfills the contract. The tests pass. ✅

The Tip: Don't judge your code during this phase. If the feature exists and works, you have succeeded at Step 1.


2. Make it right

Now that you have peace of mind (the code works), it's time to put on your Architect hat. This is where Refactoring happens.

The goal is to make the code readable, maintainable, and testable for "Future You" (who will hate "Present You" if you leave the code in the state of Step 1).

The Actions:

The JS Example (Refactored):

It's clean, legible, and modern.test.js
JavaScript
// Phase 2 : C'est propre, lisible et moderne.
const formatUserName = (user) => `${user.firstName} ${user.lastName}`.toUpperCase();

const getAdultUserNames = (users) => {
  return users
    .filter(user => user.age >= 18)
    .map(formatUserName);
};

We are using filter and map for a declarative approach. We extracted the formatting logic. The code now tells a story.


3. Make it fast

This is the most dangerous step, and often the most unnecessary. As Donald Knuth famously said: "Premature optimization is the root of all evil."

In 90% of web development scenarios, Step 2 is enough. Modern JavaScript engines (V8, SpiderMonkey) are incredibly fast. However, if you are processing massive datasets or notice actual UI lag, then—and only then—do you optimize.

The JS Example (Optimized): Imagine we have 1 million users. Chaining .filter() and .map() creates two intermediate arrays in memory. For pure performance, we might switch to a single pass using reduce.

Memory optimizationtest.js
JavaScript
// Phase 3 : Optimisation mémoire (seulement si nécessaire !)
const getAdultUserNamesOptimized = (users) => {
  return users.reduce((acc, user) => {
    if (user.age >= 18) {
      acc.push(`${user.firstName} ${user.lastName}`.toUpperCase());
    }
    return acc;
  }, []);
};

We sacrificed a tiny bit of readability to gain performance (one iteration instead of two).


Why is the order vital?

If you mix up the order, you run into major issues:

In Summary:

So, the next time you open your code editor, take a deep breath. Just make it work. The rest will follow.