Code readability

Characters per line

Prettier defaults to 80 characters per line. The optimal line length to favor text readability is around 50~60 characters.
Like for text, it's harder to jump the next line when you're at the end of a very long line.

Removing unecessary characters

Examples:

() => { return [1, 2]; }
// can be shortened to
() => [1, 2]
 
() => { return {/*an object*/}; }
// can be shortened to
() => ({/*an object*/})
 
[].map((x) => mapToY(x))
// can be shortened to
[].map(mapToY)
 
<Component field={'string'} />
// can be shortened to
<Component field="string" />
 
if(a!== null && a !== undefined) { return a; } else { return b; }
// can be shortened to
a ?? b
 
// use type inference :
const two: () => number = () => 2;
// can be shortened to
const two = (): number => 2;
// can be shortened to
const two = () => 2;

Small line length and removing unecessary characters makes navigating in code faster.

Inlining small "magic strings" or "magic numbers" (pros & cons)

Always extracting them is a cargo cult (https://en.wikipedia.org/wiki/Cargo_cult_programming (opens in a new tab)).
The best description for a "magic" string or number is often its value.
For example, if (user.age < 18) vs if (user.age < MIN_AGE)
where const MIN_AGE = 18 is declared somewhere else in the code.
The reader has to navigate to MIN_AGE to understand the code, which can create context-switch.
Numbers and strings are immutable in JS. Extracting them doesn't help with equality.
Typescript make them easy and safe to use via type YesNo = "yes" | "no".
If the value becomes hard to parse and equality check for a human reader, extracting will make it easier at the cost of navigation.
An example where extracting helps is colors in a design-system, grey100 is easier to understand, remember and use compared to "#E1E1E1".

Shortening too long and descriptive names (pros & cons)

Long and descriptive name favors understanding the writer's intent, but not what the code actually does.
They increase line length & line wrap, are harder to parse for a human reader (it's hard to tell among long names which is which).
As an example, userFromDatabaseWithAge can probably be shortened to user, and the extra information kept implicit. Researches show that long and descriptive name don't help prevent/fix bugs : http://www2.unibas.it/gscanniello/Giuseppe_Scanniello%40unibas/Home_files/TOSEM.pdf (opens in a new tab) (summary: https://hillelwayne.com/post/the-best-se-paper/ (opens in a new tab) ) ex: https://www.codesimplicity.com/wp-content/uploads/2022/05/CodeSimplicity.pdf (opens in a new tab) "Readability" chapter (long vs short, spaced vs compact...).

Long names are also harder to manipulate as text. Most commonly used navigation keyboard shortcuts go to next/previous/specific word, or line start/end. Editing a long camelCase name for example tend to require more effort, like switching to camel hump mode.

Single character variables

In situations like map/filtering an array, the name of the variable is often redundant, using a single character won't obfuscate the code in simple scenarios. ex:

users.filter((u) => u.age >= 18)

Number of line per file

No perfect size & quite subjective.

A 2K screen fits around 60 lines of code, a MacBook Pro 15" screen fits around 40 lines of code.
Books tend to have around 50 lines per page.

Using organic navigation (via "go to reference" / "find implementations") exclusively with 1 file open can make small files easier to navigate. On the other hand, someone who uses shortcuts like ctrl+tab to navigate between files might have a harder time when too many files are open.

Component-based separation of concern: jsx & css & i18n & etc in the same file

It's often easier to picture what a component looks like when you can see the css and the i18n strings.

CC BY-NC 4.0 2024 © Shu Ding.