Summary 📑
- Soft tabs with two spaces
- Never use semicolons
- Always use single quotes
- Keep
else
in the same line of closure of theif
- Add spaces between operators
- Avoid single letter names
- Use lowerCamelCase
- Use the === operator
- Add spaces outside parentheses
()
but avoid it inside - Use function expressions instead of function declarations
- Anonimous function
- Ternary operator single line only
- Don't be dumb with ternary operator
- Use
const
for all of your references, avoid usingvar
- If you must reassign references, use
let
instead ofvar
- Declare one
const
orlet
per declaration statement - Use the literal syntax for
object
creation - Use the literal syntax for
array
creation - Declare
array
items in list - Function arguments indentation
- Method chaining
- Any non-trivial conditions must be assigned to a variable or function with a descriptive name
- Try to write comments that explain higher level mechanisms or clarify difficult segments of your code
- Don't use comments to trivial things
- References
Soft tabs with two spaces
Eslint: indent
- Wrong:
if (true) {
console.log('True')
}
- Correct:
if (true) {
console.log('True')
}
Never use semicolons
Eslint: semi
- Wrong:
if (true) {
console.log('True');
}
- Correct:
if (true) {
console.log('True')
}
Always use single quotes
Eslint: quotes
- Wrong:
if (true) {
console.log("True")
}
- Correct:
if (true) {
console.log('True')
}
Keep else
in the same line of closure of the if
Eslint: brace-style
- Wrong:
if (true) {
console.log('True')
}
else {
console.log('False')
}
- Correct:
if (true) {
console.log('True')
} else {
console.log('False')
}
Add spaces between operators
Eslint: space-infix-ops
- Wrong:
for (i=0;i<10;i++) {
...
}
- Correct:
for (i = 0; i < 10; i++) {
...
}
Avoid single letter names
Be descriptive with your naming. Eslint: id-length
- Wrong:
function q() {
...
}
- Correct:
function query() {
...
}
Use lowerCamelCase
Eslint: camelcase
- Wrong:
let is_error
- Correct:
let isError
Use the === operator
Eslint: eqeqeq
- Wrong:
const example = 'Is a example'
if (example == 15) {
...
}
- Correct:
const example = 'Is a example'
if (example === 15) {
...
}
Add spaces outside parentheses ()
but avoid it inside
Eslint: keyword-spacing
- Wrong:
if(condition){
...
}
- Correct:
if (condition) {
...
}
Use function expressions instead of function declarations
Eslint: func-style
- Wrong:
function foo() {
}
- Correct:
const foo = function () { }
When you must use function expressions (as when passing an anonymous function), use arrow function
notation
Eslint: prefer-arrow-callback
- Wrong:
[1, 2, 3].map(function (x) {
const y = x + 1
return x * y
})
- Correct:
[1, 2, 3].map((x) => {
const y = x + 1
return x * y
})
Ternary operator single line only
The ternary operator should be used on a single line.
- Wrong:
const foo = (condition)
? 1
: 2
- Correct:
const foo = (condition) ? 1 : 2
Don't be dumb with ternary operator
Disallow ternary operators when simpler alternatives exist. Eslint: no-unneeded-ternary
- Wrong:
const isYes = answer === 1 ? true : false;
- Correct:
const isYes = answer === 1;
Use const
for all of your references, avoid using var
Eslint: prefer-const
- Wrong:
var foo = 'bar'
- Correct:
const foo = 'bar'
If you must reassign references, use let
instead of var
Eslint: no-var
- Wrong:
var count = 1
if (condition) {
count += 1
}
- Correct:
let count = 'bar'
if (condition) {
count += 1
}
Declare one const
or let
per declaration statement
Eslint: one-var
- Wrong:
const foo = require('./bar'),
foo = require('./foo')
- Correct:
const foo = require('./bar')
const foo = require('./foo')
Use the literal syntax for object
creation
Eslint: no-new-object
- Wrong:
const foo = new Object()
- Correct:
const foo = {}
Use the literal syntax for array
creation
Eslint: no-array-constructuor
- Wrong:
const foo = new Array()
- Correct:
const foo = []
Declare array
items in list
>= 4 arguments: indent. Eslint: array-element-newline and array-bracket-newline
- Wrong:
const foo = [
'hello', 'world'
]
const foo = ['hello', 'world', 'lore', 'impsum']
- Correct:
const foo = ['hello', 'world']
const foo = [
'hello',
'word',
'lore',
'impsum'
]
Function arguments indentation
>= 4 arguments: indent (excerpt callbacks brackets). Eslint: function-paren-newline
- Wrong:
const foo = (
'lore',
'impsum'
) => {}
const foo = ('carls', 'farls', 'karen', 'logan') => {}
foo.bar(
'string',
() => {
statements
}
)
- Correct:
const foo = ('lore', 'impsum') => {}
const foo = (
'carls',
'farls',
'karen',
'logan'
) => {}
foo.bar('string', () => {
statements
})
Method chaining
Eslint: newline-per-chained-call
- Wrong:
user
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true
})
user.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true
})
- Correct:
user
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true
})
Any non-trivial conditions must be assigned to a variable or function with a descriptive name
- Wrong:
if (password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)) {
...
}
- Correct:
const isValidPassword = password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)
if (isValidPassword) {
...
}
Try to write comments that explain higher level mechanisms or clarify difficult segments of your code
- Wrong:
const foo = "var(--bar)"
// Regexp
if (foo.replace(/var\(/, "").replace(/\)/, "") === "--bar") {
...
}
- Correct:
let foo = 'var(--bar)'
let value = foo
.replace(/var\(/, '') // Remove the 'var('
.replace(/\)/, '') // Remove the ')'
if (foo === '--bar') {
...
}
Don't use comments to trivial things
- Wrong:
// Create the passwors
const password = 'carls1234'
- Correct:
const password = 'carls1234'
References
Project inspired by valle-style-guide
Top comments (52)
Couple of things:
const msg = "Why wouldn't I?";
.const msg2 = 'Must I suffer because of someone else\'s preference by escaping the single quote everywhere?';
this
keyword. So no to that one too.That's me. Problematic guy for sure. 😄
You can also use template literals instead, if you need to use single or double quotes in a string.
How about using correct characters instead?
I can't add too much to the code formatting question, because I use Prettier, which does the job. I think I use two spaces then Prettier does it better:) I never thought about it, it's in the muscle memory:)
The arrow function thing is interesting. The reason, why these were introduced to ES6, is that they do not bind the value of 'this' but inherit it. I have tiny code sample to show this in the arrow-function-example repository. The important point is that in some cases you should use arrow functions if you want to avoid binding 'this' explicitly in a regular function. It was important for some cases for event handling in React class components. Function components behave differently, so it's not so important in modern React. There are other cases, when you can't use arrow functions for the same reason. I met some cases when I used mongoose. There are cases, when arrow functions do not cause error, but not recommended for efficiency reasons. For example arrow functions shouldn't be used as methods in ES6 classes, because they become instance methods instead of prototype methods. In practice it means if you had 100 instances of the same objects the method is stored in the memory in all the 100 instances in the case of arrow function. In the case of the regular function the method is only stored once in the prototype object.
It's been years and I have yet to see anyone make a coherent argument for spaces, or to even address the multitude of reasons why tabs are objectively better for indentation.
At this point I'm starting to think it's just clueless programmers intentionally placing hints in their code that it's not worth reading.
Every now and then you need semicolons to disambiguate your code though. "Never" and "Always" rules are just dumb. Know the language, and know when you need to use them, otherwise don't.
Quote styles is the dumbest red herring one could come up with. Who cares. Just be reasonably consistent within files and no sane person will care about it.
Just avoid short names in general;
query
is still a bit short for my taste; it doesn't tell me what is being queried. The builtin browser APIs are doing this right:document.querySelectorAll
tells you everything you need to know, even if you don't know that particular function.Again, this is a really dumb rule. Use whichever you need. Sometimes you may want
==
, or you may know your input types.I despise people who do this. It works for short conditions, like
1
and2
, but for longer expressions, it just makes the code much harder to read for no reason whatsoever. It's just making people's lives harder.I like this example because it perfectly encapsulates why this sort of thing usually isn't a matter of how you format your code, but of how it's structured. Here's a better way of doing the same thing:
All in all, these style guides always make me think if people put any degree of thought into how appropriate they are for collaborative projects, or just note down their personal preferred code style to lend it legitimacy and to push it onto others.
Tabs FTW 👍
Anything is fine with me, but a big, big, big no to tabs for indenting!
Do anything you want, I don't care, but tabs for indenting (or using any kind of non-printable characters in source code for that matter, except for linefeeds) are such a huge no-no for me.
...so you don't use spaces in your source code either?
Spaces are printable, I can clearly count the number of spaces (15) in this sentence :)
Here, count these:
Nice try lol, but the point was about printable/countable characters in my editor or in an IDE, not in a dev.to comment ... so, in my IDE I can press a key to move the cursor to the end of the line, which would shows me spaces there if any, and which would allow me to count them - UNLESS someone made the inane decision to use tabs.
(and most likely I'd have a setting in my IDE or editor to strip trailing spaces on save anyway)
I'll say it again - using TABs in source code is evil.
You're not making any sense. If you just feel an emotional attachment to spaces, then just say that. Making up incoherent excuses about counting spaces (wtf?) won't make using spaces any less annoying anyway.
Emotional attachment, "incoherent excuses", "I don't make any sense" - I think you're projecting there, you know about the pot and the kettle?
I'm just saying that for me tabs or other non-printable characters (with the exception of linefeeds) shouldn't be in source code, for practical (not for emotional) reasons. Just use tabs if you like, I don't care as long as I don't need to use your source code, lol.
P.S. what I dislike (I'm putting this politely) is that it goes against the grain of what at least 90% of devs are doing, and what I see in more than 95% of the codebases - spaces is the de facto standard, simple as that.
But no, "we" insist on doing things "our way", because we don't care about others, and we really love to make things more complicated and annoying for everyone else ... LOL !
I don't care much how people format their private code, I'm just opposed to using spaces in code that's meant for others to interact with, for a variety of reasons that amount to "It's not my business to dictate how others read code".
From the advocates of spaces, however, the only argument I have ever heard is an entitled notion of wanting to dictate how their code must look on other peoples' screens and the inability to configure their own editor.
So in short: Spaces are harmful, be a better person and use tabs.
That being said, this is of course a very minimal issue at the end of the day, and it's not like using spaces automatically makes anyone a monster; it's no more than a preventable annoyance.
When 95% (more, probably) of the devs and codebases are using spaces, not tabs, then spaces are the de facto standard. It doesn't really matter which is better - you're deviating from a de facto standard, which means you're the one who's upsetting and annoying, simple as that.
In many cases it doesn't matter what we do, all that matters is that we stick to doing the same thing in order to avoid friction and confusion. I'll leave it at that, use tabs in your private codebases, which I'll stay far away from.
I'm sorry, but if you think "Everyone does it" is a reasonable argument, then you have a lot of growing up to do before you're capable of having this discussion.
I do think it's a good argument, it's called "pragmatism" ... no comment on the 'growing up' thing, I'd say let's keep the ad hominems out of this discussion.
Call it whatever you like, pragmatism, conformity, bob... It's still ultimately an appeal to popularity that makes no sense whatsoever. If there is a good reason to prefer spaces over tabs, then neither you nor anyone else I've met has been able to explain it so far.
Edit to add: And maybe don't try using big words like "ad hominem" when you don't actually know what they mean. It just makes you look worse.
LOL oh yes, you assume that I use the word "ad hominem", without knowing what it means - okay, I'll give you an example:
You said that I "have a lot of growing up to do" - that's an example of an ad hominem, you're targeting the person rather than the topic, got it?
Ohhhh but I use "ad hominem", but, I really don't know what it means - LOL !
P.S. by pragmatism I simply mean that if 95% or 99% of the world are using spaces, and if the pros or cons of spaces over tabs or the other way around are really marginal (which they are), then I'll use spaces simply in order not to complicate or to confuse matters or to annoy that vast majority of people by foisting my petty little preference on them - because it isn't worth it ... if the advantages of tabs over spaces would be significant and non-trivial then rest assured that I'd be the first one to adopt them.
No, I am not assuming, I am telling you, because it is obvious from how you use the word that you have no actual understanding of what it means, and this comment confirms that once again.
And ironically, this just confirms my statement which you were complaining about: You still have a lot of growing up ahead of you before you're worth having any nuanced discussion with, if you think the best reaction to being told you're misunderstanding a word is to just double down and dig yourself in deeper.
The benefits of tabs aren't world-changing, but they are significant. Reading code with 2 spaces is a lot harder on my eyes than increasing that to just one more space, so for me being able to customise my indentation width is a huge improvement. If that's "marginal" to you, then congratulation, I can't force you to give a fuck about my problems, but I can insist that makes you a worse person.
That is literally what you're doing. I'm telling you: Let me choose my indentation width, and you are here crying and moaning about why I can't be allowed to read code the way I want it because a loud minority of people can't be fucking bothered to spend three minutes configuring their code editor. You're not advocating against "foistering preferences on others", you're advocating precisely for that.
As we've established, your fellow programmers finding it easier to read your code isn't worth your time to consider, so I wonder what you would consider significant at this point. Presumably being cool and doing what everyone else does, as that is the only attempt at an argument I've seen from you.
I give up, this is hopeless. I'm not reading any new arguments, just repetition of previous statements with some haughty verbiage added in.
I gave you the most clearcut example of an "ad hominem": you're telling me that I have "growing up" to do, which means you're calling me immature. LOL - how much more of a clearcut example of an ad hominem so you want? I can't come up with a better example.
But no, you still maintain that I don't understand what the word means - it's just that you're not backing that up with any facts, you just repeat what you've already said. You're "not assuming", no you're "telling me" ...so that's the style of discussion we have here, dictates. Yes, you're "telling me" ... LOL.
I'm not going to waste time replying to the rest of the arguments, as all of it is heavily "the pot and the kettle" level stuff - you know that one, the pot and the kettle? Or you're again going to "tell me" that I don't understand what that means?
But hey I'm not taking any of this too seriously anyway, like most discussions here on dev.to it's mainly entertainment. People are taking themselves too seriously, putting themselves on some sort of comical pedestal.
I'll give you a clear example of being 'grown up': I'm going to wish you a nice day, and I genuinely mean it!
— thefreedictionary.com
— Rational Wiki
— Wikipedia
And I'm sure you can find more if you google them. Have fun learning.
Hey whatever ... I think that "argument that attacks not an opponent's beliefs but [their] motives or character" comes close enough, mister would-be philosopher.
Have a nice day again, I think we can close this off now.
Not a mister, but okay :)
Ah apologies, hadn't really paid attention to your profile pic, my bad!
What do I do If I am ugly ?
You compensate by writing pretty code instead, starting with using tabs 😉 😝
Tabs are the incarnation from hell. Tabs makes your code look one way in editor A, but another way in editor B. Spaces is the only sane option! 😡
There is exactly one person who has any business deciding what indentation level any code appears in in my editor, and that's me.
Everyone else has exactly the same authority over my preferred indentation level as over my colour theme. That's the whole point of tabs: You don't have to read my code in 3-space indentation if you don't want to, and I don't have to read yours in whatever you prefer.
Arguing for spaces is really just trying to shove ones preferred indentation level down everyone else's throat.
And I'm sorry but the "I'm too dumb to configure my editor" argument just doesn't make sense. Any modern code editor will let you change your tab width. This is extremely silly.
I agree with your point in theory, but tooling in real life is not always helpful. You don't always have the ability to set your tab size in a tool. Spaces is the only sane path.
Call me idealistic, but I don't think bad tools should be an excuse for bad practices. It's the tools that need to change, not the code.
I agree. The tools need changing. But I won't suffer while they decide to do it. So spaces.
While I agree with most of the rules you included, this is highly opiniated and just your style, which you shouldn't impose upon others (I feel that's implied from "if you're beautiful"). Some things are 100% up to the programmer's personal taste, e.g. whether to use double quotes or semi colons.
I think one thing lacking from this article is why. Why should I follow those guidelines, and what benefits are there? Sure, I believe you should have meaningful variable names and spaces between operators, but does it actually matter whether you use double quotes or not? I feel like this guideline was formed solely for your visual pleasure in "beautifully formatted code".
Besides that, I think you could have simply left the article to Prettier or something. Just type your code and have Prettier do the annoying formatting for you. I like their presets anyways.
P.S. What do you have against functional declarations? In my opinion declaring the function as an expression looks really ugly and should only be done for arrow functions.
I'll let semicolon as an option for the dev. About the rest, i'm agree with @brense about keeping a clear idea of what we're doing using both function keyword and getting the expressions into const. Good post btw 😁!
Not bad
I also use air-bnb style guide
Single quotes for strings is an aberration. In C, a char array would use double quotes and a single character would use single quotes. It matters a lot as they are 2 completely different definitions (zero ended uint8 array vs uint8).
If you are a decent old-school programmer, you will NEVER use single quotes for strings. The same for the semicolon. Optional semicolon is also an aberration decision for JS and not using it denotes a genZ that only knows JS, Python and maybe Java because of high school.
Damn late millenials... [Insert old man yelling at clouds gif here]
Agree with everything except function expressions instead of declarations. Being concise is always better imho and using the
function
keyword is clearer than turning everything into an expression and assigning to const. Besides that, function declarations are also functionally different from function expressions in terms of scope.Great article though, with good examples! 👍
Two spaces aren’t enough for readability. It’s a legacy code style from the bad old days of extremely nested callbacks.
Function expressions are ugly, verbose and unnecessary. Just use
function foo() {/*...*/}
at the top level. There's probably a good case for using function expressions where you need functions inside functions; in that case, use an arrow function to avoidthis
issues.