Kobotoolbox uses Biome mainly for formatting, and ESLint exclusively for linting.
- formatting: consistent whitespaces and other style of code.
- linting: identifying bugs and anti-patterns.
Kobotoolbox has plans to adopt oxlint in the future. It's an upcoming performant competitor to ESlint, but isn't type-aware yet and thus limited in it's capacity.
-
tag
@deprecated
when deprecating code and explain what to do instead. FYI VSCode nicely strike-through deprecated code.- example TS/JSDoc syntax to deprecate external dependencies:
declare namespace JQuery { /** @deprecated use fetch instead */ export interface jqXHR { } }
- example TS/JSDoc syntax to deprecate external dependencies:
-
don't use
@deprecated
code.
- singular for objects (
user
), plural for arrays/maps/etc (users
), suffix for primitives (userName
). - don't use Systems Hungarian (e.g.
strExample
), because let's don't duplicate intellisense. Except for boolean type, because it reads nice, e.g.isExample
,hasExample
, etc. - use Hungarian Notation where appropriate (indicate kind of the type). Examples:
input
andinputSanitized
or other way aroundinputRaw
andinput
, your choice. - boilerplate snippets:
const exampleQuery = useExampleQuery()
for react query hook usage.import cx from 'classnames';
for classnames import.
Main principle is, keep related code close for modularity. Organize by feature/usage/concept, not type (images at images, etc.). Sanity check question: if requirements would change, what parts of code would likely be changed or deleted together as a bundle?
- organize folders and subfolders by root/global, feature, sub-feature, sub-sub-feature, …. Each level may have generic
common
,components
andhooks
folders. Place code as deep as possible to be above or next to all it's consumers. Update as consumers change. Example:/ jsapp/ common/ # <-- (4) reused non-react-stuff globally go here. components/ # <-- (4) reused components globally go here. hooks/ # <-- (4) reused hooks globally go here. BigFeat/ common/ # <-- (3) reused non-react-stuff within feature go here. components/ # <-- (3) reused components within feature go here. hooks/ # <-- (3) reused hooks within sub-feature go here. index.tsx BigFeatTable/ common/ # <-- (2) reused non-react-stuff within component goes here. components/ # <-- (2) reused components within component goes here. hooks/ # <-- (2) reused hooks within component goes here. index.tsx # <-- (1) small helpers or interfaces are co-located inside # component or hook files, and are not exported. useExample.ts # <-- (1) files specific only to other file(s) # in the same folder stay next to them.
- organize files by concerns and name it by that. Keep one concern per file. Don't shy away from small but focused files.
- one React component per file and name it the same —
Example.tsx
orExample/index.tsx
. - one React hook per file and name it the same —
useExample.tsx
oruseExample/index.tsx
. - for anything big and/or complex enough, have a seperate file and name it the same.
- it's ok to co-locate in the same file several similar variations of the same, as well accompanying constants, helpers, type-guards and other utils.
- one React component per file and name it the same —
- every folder has a meaningful
index.tsx
files, exceptcommon
,components
, andhooks
folders. Index file contains and/or re-exports what consumers outside of folder imports (kinda as folder's API). - Include type of file in filename only for tests and storybook. Such as:
{index,Example}.tsx?
{index,Example}.stories.tsx
{index,Example}.{spec,test}.tsx?
useExample.tsx?
useExample.{spec,test}.tsx?
- use Typescript, don't use Javascript.
- use React functional components and hooks instead of classes and HOCs.
- for response caching use
react-query
, don't reinvent cache using state.