You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We're in a period where we are looking at what other Javascript/TypeScript linters are doing out of growing dissatisfaction with several facets of the current one, eslint.
Still the main role we should give to a linter is to give us a useful analysis, so I looked at all rules we currently enabled on eslint and checked if they are present in biomejs, and reported the result in this issue.
Note that this may not be the only differences between linters, biomejs seems to e.g. not want to implement multi-line inline rule ignoring (like eslint-disable), which we rarely but do rely on, though I'm sure we could work-around that one.
Also I did not look at the other way around yet (rules in biomejs we would like that are not in eslint currently).
I organized rules into categories described in the chapters below.
Missing rules that are needed
I consider those eslint rules very important, and I'm reluctant to switch to biome just because of those:
@typescript-eslint/strict-boolean-expressions (ensures conditionals rely on explicit booleans)
Status: Some user talked about it recently in biome's discussions/3533 and in discussions/3. It may rely on better TypeScript inference which is tracked by biome's issues/3187
Reasons for which I consider this one important: I found that it is a nice way to force explicit checking in conditions and not fall into Javascript truthy/falsy traps (such as unexpected falsy special values like the empty string, 0, NaN etc.).
(checks that some TypeScript types are never used)
no-restricted-properties (Checks that some properties are never accessed)
Status: Some user talked about it recently in biome's discussions/3
Reasons for which I consider this one important: Allows us to both forbid usages of performance.now and of window, both for worker<-> main thread interaction reasons.
Missing rules that I find nice to have
I find these rules nice to have, but could live without if the other linter is really tempting:
@typescript-eslint/await-thenable (ensures that awaited object have a then property)
NOTE: A maintainer referenced it in June 12 in biome's issues/3187, so it's planned.
@typescript-eslint/no-floating-promises (ensure promises are catched)
NOTE: acknowledged both in biome's discussions/3 and biome's issues/3187
@typescript-eslint/no-for-in-array (ensures we do not rely on for..in with arrays)
NOTE: Referenced in biome's issues/3187, like await-thenable and no-floating-promises.
@typescript-eslint/no-shadow (ensures we're not shadowing variables)
NOTE: Referenced in biome's discussions/3 and discussions/535, a maintainer is "not against adding this rule" (his words).
@typescript-eslint/no-unnecessary-boolean-literal-compare (alerts if we're unnecessarily doing things like === true on booleans)
NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/no-unnecessary-type-assertion (ensures that type assertions change the actual type)
NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/no-unused-expressions (ensures expressions perform some kind of side-effects)
NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/restrict-plus-operands (ensures + is performed on similar types in the left and right hands)
NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/unified-signatures (check that two signatures can be merged)
NOTE: in biome's issues/50
import/no-duplicates (checks for duplicate imports, and propose to merge them):
NOTE: no info on that one
no-invalid-this (ensures this is not used in places where it makes no sense)
NOTE: no info on that one
no-template-curly-in-string (ensures that we're not setting ${myVariable} in non-template strings which is often a mistake, that's hard to see)
NOTE: no info on that one
object-shorthand (ensures { r: r } is just set to { r })
NOTE: no info on that one
radix (ensures a radix agument is set on parseInt calls)
NOTE: no info on that one
Missing rules I don't care really about (sorry, rule)
We could also remove it from eslint, I wouldn't cry about it much (yet I would for the other ones):
@typescript-eslint/consistent-type-assertions
@typescript-eslint/consistent-type-definitions
@typescript-eslint/no-unnecessary-qualifier
@typescript-eslint/no-unnecessary-type-arguments
@typescript-eslint/no-var-requires
@typescript-eslint/triple-slash-reference
@typescript-eslint/unbound-method
ban (We relied on it to awkwardly ban Promise.prototype.finally with many potential false positives)
guard-for-in
import/no-deprecated
jsdoc/check-alignment
max-classes-per-file
no-caller
no-nested-ternary
no-return-await
prefer-object-spread
prefer-spread
Special cases
@typescript-eslint/array-type
Status: It actually exists as lint/style/useConsistentArrayType, but there's no array-simple concept like we had.
Opinion: I don't really care that much for that rule actually, I could also disable it and let people pick their favorite one if they want to.
@typescript-eslint/no-this-alias:
Status: technically not the same thing, lint/complexity/noUselessThisAlias just checks that a this aliasing is necessary at all.
Opinion: This is OK for me, I don't personally care for the initial rule.
eqeqeq:
Status: theoretically OK as lint/suspicious/noDoubleEquals, but the latter authorize == null, which is something we want to actively forbid :/
Though a very mysterious developer lately implemented that option and it has been merged, so surely in a future version.
spaced-comment
Status: It is actually also deprecated in eslint and moved to some eslint plugin for some reason.
Opinion: I don't much care about that one, can be removed.
Just to come back to this issue, here's what I conclude:
The formatting part of the tool is very nice, much faster than prettier (which is honestly TOO slow).
But it has a very big drawback: It does not handle Markdown. We heavily rely on markdown for documentation (being the second language of the RxPlayer in terms of LOC, above even JavaScript :p) and we often read them directly in a text editor, so formatting Markdown files automatically was a very nice feature I don't think we want to lose.
So until then, I say we stay on prettier. Markdown is planned though, but it comes after HTML and CSS in their roadmap (turns out many JavaScript projects have a lot of HTML and CSS files and thus it's more important to them, crazy I know).
The linting part misses the rules described above and the great majority of them (and the most needed ones) seems to be linked to type information.
Here the status is more complex: they don't want to rely on the typescript package to perform type inference (such as typescript-eslint does) because typescript is slow and being fast is one of their main selling point.
I'm unsure of how they will advance on that point, by compiling biome's website, their GitHub, and hacker news posts from the contributors (it's not stalking if it's for work) they might rely on the very new TypeScript's --isolatedDeclaration feature which seems to force much more explicit type declaration (I'll have to check what it does exactly). To check.
A solution some applications seem to choose is to have both biome and eslint (and maybe get rid of prettier). Biome to quickly analyze and format code locally, and eslint running on the CI.
Faster local checks are not a sufficient reason to me to be adding another dependency on top of the rest (because of the complexities it might add).
When biome will handle Markdown formatting and/or TypeScript checking, we could re-ask ourselves the question though.
We're in a period where we are looking at what other Javascript/TypeScript linters are doing out of growing dissatisfaction with several facets of the current one, eslint.
Still the main role we should give to a linter is to give us a useful analysis, so I looked at all rules we currently enabled on eslint and checked if they are present in biomejs, and reported the result in this issue.
Note that this may not be the only differences between linters, biomejs seems to e.g. not want to implement multi-line inline rule ignoring (like
eslint-disable
), which we rarely but do rely on, though I'm sure we could work-around that one.Also I did not look at the other way around yet (rules in biomejs we would like that are not in eslint currently).
I organized rules into categories described in the chapters below.
Missing rules that are needed
I consider those eslint rules very important, and I'm reluctant to switch to biome just because of those:
@typescript-eslint/strict-boolean-expressions
(ensures conditionals rely on explicit booleans)Status: Some user talked about it recently in biome's discussions/3533 and in discussions/3. It may rely on better TypeScript inference which is tracked by biome's issues/3187
Reasons for which I consider this one important: I found that it is a nice way to force explicit checking in conditions and not fall into Javascript truthy/falsy traps (such as unexpected falsy special values like the empty string,
0
,NaN
etc.).(checks that some TypeScript types are never used)
no-restricted-properties
(Checks that some properties are never accessed)Status: Some user talked about it recently in biome's discussions/3
Reasons for which I consider this one important: Allows us to both forbid usages of
performance.now
and ofwindow
, both for worker<-> main thread interaction reasons.Missing rules that I find nice to have
I find these rules nice to have, but could live without if the other linter is really tempting:
@typescript-eslint/await-thenable
(ensures that awaited object have a then property)NOTE: A maintainer referenced it in June 12 in biome's issues/3187, so it's planned.
@typescript-eslint/no-floating-promises
(ensure promises are catched)NOTE: acknowledged both in biome's discussions/3 and biome's issues/3187
@typescript-eslint/no-for-in-array
(ensures we do not rely onfor..in
with arrays)NOTE: Referenced in biome's issues/3187, like
await-thenable
andno-floating-promises
.@typescript-eslint/no-shadow
(ensures we're not shadowing variables)NOTE: Referenced in biome's discussions/3 and discussions/535, a maintainer is "not against adding this rule" (his words).
@typescript-eslint/no-unnecessary-boolean-literal-compare
(alerts if we're unnecessarily doing things like=== true
on booleans)NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/no-unnecessary-type-assertion
(ensures that type assertions change the actual type)NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/no-unused-expressions
(ensures expressions perform some kind of side-effects)NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/restrict-plus-operands
(ensures+
is performed on similar types in the left and right hands)NOTE: no information on that one on biome's side, maybe once their TypeScript parser is done?
@typescript-eslint/unified-signatures
(check that two signatures can be merged)NOTE: in biome's issues/50
import/no-duplicates
(checks for duplicate imports, and propose to merge them):NOTE: no info on that one
no-invalid-this
(ensuresthis
is not used in places where it makes no sense)NOTE: no info on that one
no-template-curly-in-string
(ensures that we're not setting${myVariable}
in non-template strings which is often a mistake, that's hard to see)NOTE: no info on that one
object-shorthand
(ensures{ r: r }
is just set to{ r }
)NOTE: no info on that one
radix
(ensures aradix
agument is set onparseInt
calls)NOTE: no info on that one
Missing rules I don't care really about (sorry, rule)
We could also remove it from eslint, I wouldn't cry about it much (yet I would for the other ones):
@typescript-eslint/consistent-type-assertions
@typescript-eslint/consistent-type-definitions
@typescript-eslint/no-unnecessary-qualifier
@typescript-eslint/no-unnecessary-type-arguments
@typescript-eslint/no-var-requires
@typescript-eslint/triple-slash-reference
@typescript-eslint/unbound-method
ban
(We relied on it to awkwardly ban Promise.prototype.finally with many potential false positives)guard-for-in
import/no-deprecated
jsdoc/check-alignment
max-classes-per-file
no-caller
no-nested-ternary
no-return-await
prefer-object-spread
prefer-spread
Special cases
@typescript-eslint/array-type
Status: It actually exists as
lint/style/useConsistentArrayType
, but there's noarray-simple
concept like we had.Opinion: I don't really care that much for that rule actually, I could also disable it and let people pick their favorite one if they want to.
@typescript-eslint/no-this-alias
:Status: technically not the same thing,
lint/complexity/noUselessThisAlias
just checks that athis
aliasing is necessary at all.Opinion: This is OK for me, I don't personally care for the initial rule.
eqeqeq
:Status: theoretically OK as lint/suspicious/noDoubleEquals, but the latter authorize
== null
, which is something we want to actively forbid :/Though a very mysterious developer lately implemented that option and it has been merged, so surely in a future version.
spaced-comment
Status: It is actually also deprecated in eslint and moved to some eslint plugin for some reason.
Opinion: I don't much care about that one, can be removed.
Rules also in biome
@typescript-eslint/adjacent-overload-signatures
(lint/nursery/useAdjacentOverloadSignatures*)@typescript-eslint/consistent-type-exports
(lint/style/useExportType)@typescript-eslint/consistent-type-imports
(lint/style/useImportType)@typescript-eslint/dot-notation
(lint/complexity/useLiteralKeys)@typescript-eslint/naming-convention
(@typescript-eslint/naming-convention**)@typescript-eslint/no-empty-function
(lint/suspicious/noEmptyBlockStatements)@typescript-eslint/no-empty-interface
(@typescript-eslint/no-empty-interface)@typescript-eslint/no-explicit-any
(lint/suspicious/noExplicitAny)@typescript-eslint/no-extraneous-class
(lint/complexity/noStaticOnlyClass)@typescript-eslint/no-misused-new
(lint/suspicious/noMisleadingInstantiator)@typescript-eslint/no-namespace
(@typescript-eslint/no-namespace)@typescript-eslint/no-non-null-assertion
(lint/style/noNonNullAssertion)@typescript-eslint/no-restricted-types
(lint/nursery/noRestrictedTypes)@typescript-eslint/no-unnecessary-type-constraint
(lint/complexity/noUselessTypeConstraint)@typescript-eslint/no-unused-vars
for our needs (lint/correctness/noUnusedVariables)@typescript-eslint/prefer-for-of
*** (lint/style/useForOf)@typescript-eslint/prefer-function-type
(lint/style/useShorthandFunctionType)@typescript-eslint/prefer-namespace-keyword
(lint/suspicious/useNamespaceKeyword)constructor-super
(lint/correctness/noInvalidConstructorSuper)curly
(lint/style/useBlockStatements)import/order
****no-cond-assign
(lint/suspicious/noAssignInExpressions)no-console
(lint/nursery/noConsole*)no-debugger
(lint/suspicious/noDebugger)no-delete-var
(lint/performance/noDelete), biome handles more cases (delete calls in general are forbidden)no-duplicate-case
(lint/suspicious/noDuplicateCase)no-extraneous-dependencies
(lint/nursery/noUndeclaredDependencies)no-empty
(lint/suspicious/noEmptyBlockStatements)no-eval
(lint/security/noGlobalEval)no-fallthrough
(lint/suspicious/noFallthroughSwitchClause)no-new-wrappers
(lint/nursery/useConsistentBuiltinInstantiation*)no-param-reassign
(lint/style/noParameterAssign)no-prototype-builtins
(lint/suspicious/noPrototypeBuiltins)no-sequences
(lint/style/noCommaOperator)no-sparse-arrays
(lint/suspicious/noSparseArray)no-throw-literal
(lint/nursery/useThrowOnlyError*)no-undef-init
(lint/nursery/noUselessUndefinedInitialization*)no-unsafe-finally
(lint/correctness/noUnsafeFinally)no-unused-labels
(lint/correctness/noUnusedLabels)no-var
(lint/style/noVar)no-void
(lint/complexity/noVoid)one-var
(lint/style/useSingleVarDeclarator)prefer-const
(lint/style/useConst)prefer-template
(lint/style/useTemplate)use-isnan
(lint/correctness/useIsNan)valid-typeof
(lint/suspicious/useValidTypeof)yoda
(lint/nursery/noYodaExpression*)*: For now in "nursery" in biome, kind of like experimental for us
**: I haven't yet checked if it covers all cases
***: Rule not used yet, but I like the idea
****: Rule actually handled by their formatter, not their linter
The text was updated successfully, but these errors were encountered: