Skip to main content

Einride Frontend Style Guide

Most Einride code styles are enforced automatically by using ESLint together with @einride/eslint-plugin, Prettier together with @einride/prettier-config and TypeScript together with @einride/tsconfig. Some code styles, however, can't (or are not yet) enforced automatically. Those styles are described in this document.

Component design

  • Prefer type ReactNode to string. Fragments allow markup and variables by natural JSX flow and is strictly more flexible.
// bad
`Button is clicked ${count} times`

// good
<>Button is clicked {count} times</>

// bad
<Input
label="How do I make parts of this string bold?!"
/>

// good
<Input
label={<>This is <b>way</b> more flexible!</>}
/>
  • Use absolute imports, which can be achieved by setting "baseUrl": "src" in tsconfig.json. This enables moving files without superflous refactoring of import paths.
// bad
import { useEinride } from "../../../../../../../hooks/useEinride"

// good
import { useEinride } from "hooks/useEinride"
  • Use formatting components when formatting raw data like distances or emissions for human readability. It enables changing format or enabling localization in one place rather than wherever it's used.
// bad
<p>The weight of the Pod is 1000 kg.</p>

// good
<p>The weight of the Pod is <Weight kg={1000} />.</p>
  • There's no silver bullet rule for when a part of the UI should be separated into a component of its own. However, when a part of the UI contains isolated state, it's often a good idea to think about making that UI a component and colocating its state with it.

  • Here's a VS Code snippet for creating a new component according to the style guide:

"New React component according to Einride style guide": {
"prefix": "nc",
"body": [
"interface ${TM_FILENAME_BASE}Props {",
" $1",
"}",
"",
"export const $TM_FILENAME_BASE = ({$2}: ${TM_FILENAME_BASE}Props): JSX.Element => {",
" return <>$0</>",
"}",
""
]
},

Project file structure

All React projects should default to this directory structure:

src/
|––assets/
|––components/
|––contexts/
|––hooks/
|––lib/
|––pages/
|––types/

assets/

Project wide media files.

components/

Root directory for all React components. Structure inside this directory can vary depending on needs.

contexts/

Project wide React contexts.

hooks/

Project wide React hooks.

lib/

Project wide utility and setup files. For example theming and API utilities.

pages/

React components intended to fill a viewport, tightly coupled to a specific URL path.

types/

Project wide types.

File naming

  • Use UpperCamelCase.tsx for React components and use the same name for the exported component.
  • Use lowerCamelCase.ts for TypeScript files that don't contain JSX.
  • Use useHook.ts for React hooks and use the same name for the exported hook.
  • Don't use file names like utils.ts as they easily become dumps for random functions. Prefer semantic names like sort.ts for a group of sorting utility functions or sortNames.ts if only one sorting utility is exposed.