Software development best practices

This post is a list of best practices that will help junior developers become productive quickly.

Style

Names are incredibly important

Well-named functions and variables will save you time because they make your code more readable. In turn you will produce fewer bugs. Well-written code reads like English. Once you follow this, comments will often become unnecessary as the names are self-documenting.

Prefer small functions

Take the habit of breaking up functions into smaller functions. Smaller functions make the code simpler because they do fewer things. Since they are simple, they are easier to write, and you will produce fewer bugs. There is no such thing as a function that's too short. A one-line function is perfectly fine. A 50 line function can probably be broken down into smaller bits. As you break them down, the names you give to these functions will make your code read like English.

Avoid pyramid indentation

Pyramids make code harder to read. Use early returns to prevent pyramids.

if (!user) {
  return;
}

Instead of

if (user) {
  // 30 lines of code
}

Process

Use ready-made components and APIs as much as possible

As a corollary, read the docs of the APIs and frameworks that your project uses as you begin working on the project, to familiarize yourself with what's readily available.

If the UI framework you use already provides buttons, pills..., use them instead of writing your own. Their components have been written by experts. They are also well tested and documented by them and the community. Writing your own is a waste of time, because even if you can make a Button or Pill component quickly with a few lines of JS and CSS, this code will not be perfectly clean on your first try. You'll have to clean it up with the help of the reviewer. Then you will still have to write unit code, and will have to maintain it as your needs grow.

Another example is if you wanted to display a date and time. You want to make it human readable and show the day of the week, followed by the month, day and time. Easy enough, you make an array to convert a numerical day of week into the corresponding day of the week... For the time, you show the hour, and then the minutes. Done? Well, for the minutes you want to make sure to pad the numbers, so that you don't end up displaying "8:0" instead of "8:00". You also need logic to convert 24-hour hours into 12-hour formats because your client wants a AM/PM format. Now add all the unit tests, and you suddenly have to write a hundred lines of code. In Javascript, there's a ready-made function called toLocaleString that does exactly that, and will save you hours.

If you copy/pasted something even once, clean it up

You want to avoid copy/pasted code as much as possible, because it pollutes the codebase, and makes it hard to fix later. It is much cleaner to move that duplicated code into a well-named function and use it in both places. Later if you find a new, better way to do it, you can modify that function, instead of hunting for all the places where you had pasted it.

A pull request should fix only one issue, even for small fixes

One might think "I'll save time if I squeeze these 3 tiny fixes in". However what may happen is, you're suddenly modifying 6 files (one for the fix and one for the unit test for each issue). The reviewer will have a hard time understanding which changes go hand in hand. The review will take longer. Then they might notice issues in your code. You might have to change your code in a significant way. Suddenly your 3 tiny fixes take several back and forths to even get a chance to merge.

Refer to official docs

It can be tempting to copy/paste the first answer on StackOverflow that you find, or follow some tutorial on YouTube in your native language. However, it is much more efficient to refer to the official docs. Let's say you want to mock a module in Jest. The best information is most probably on the Jest documentation itself. For basic use cases like these, if you try and follow some random Youtuber, or poster, chances are, they also don't understand what they are talking about. So you end up with very diluted or plain wrong information.

If something breaks, think of the possible causes first, then Google it

Your compiler throws a cryptic error that you've never seen before, and you don't even know what it means. What to do? Before you Google that error, think of what might cause an error. Even if you don't understand the error, you might find some key words related to something you know. Once you've found several causes, you can try to simplify your code to see if the error still persists. It is helpful to reduce the error to the minimal example. Then you can Google it. Having done this prep work will help you determine which answers are most relevant to your problem. In turn you'll find the right fix to your issue much faster, than trying blindly everything you find on StackOverflow.

If the build is broken, fix it in one single pull request

If a unit test is broken on the main branch, fix this unit test in only one pull request (PR). Since the unit test is already broken in main, it is ok to build unrelated features in PRs in which the same test is also broken. If you find a fix, and try to include it in all open PRs, just to make tests pass, you run the risk of wasting time. What if the fix you had found is not the right one? What if your fix is the right one, but needs some clean ups? Now you have to apply those clean ups to all the open PRs.