Best Practices

Code readability and maintainability is our number one priority, so please enjoy this guide to our best practices and useful resources!

Development#

  • Test, test, test - see our Testing guide

  • Use functional principles

    • don't use var
    • const over let
    • map, filter, reduce over loops
  • Styling should be handled by the design system most of the time

Resources#

Tools#

  • Use prettier - We higly recommend the prettier plugin for VS Code and to stick with the default rules

  • React Devtools - React DevTools is available as a built-in extension for Chrome and Firefox browsers. But this package enables you to debug a React app elsewhere (e.g. a mobile browser, an embedded webview, Safari, inside an iframe).

  • Webpack Bundle Analyzer - Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap.

React#

We encourage developers to use React for all new development. React is considered to be easy to pick up and enables fast development.

  • Be DRY (don't repeat yourself) - don't recreate components or functions that we already have available

  • Folder structure

    • Keep components, constants, models, and pages all in separate folders
    • Component and Pages folders should include related styles, if necessary, and an index file
    • Component files - PascalCase eg ContactList.tsx
    • All other files - kebab-case eg use-fetch.ts
  • Components should be easy to read and test

    • Prefer existing components over basic HTML tags - e.g. <Typography.Paragraph> over <p> for typography.
    • Keep components small and single purpose
    • Write functional components rather than class-based
    • Separate statefullness from rendering concerns - e.g. fetch data in hooks and have a dumb component render it
    • Don't write inline functions/defined functions in render() - it affects performance
    • Use PascalCase for naming components
  • Don't write custom CSS.

    • Use the default styles applied to our components
    • If a design does not match the default styles of our Design System, bring it up with the designer. Either the design does not adhere to the Design System, or the shared component is styled improperly and needs to be fixed.
  • Keep your state as simple as possible

    • Don't use a 3rd party state management library unless you absolutely have to
    • Don't store derived state
    • Keep state in as few components as possible
    • Avoid excessive prop drilling
  • Different ways you can store your application state:

    • Component state - Using the useState Hook. It stores data within the given component and persists throughout renders
    • Instance variables and mutatable refs
    • Context
    • React-Redux using Connect/Hooks - not recommended unless you absolutely need it since it adds a lot of overhead
  • useState vs useReducer

  • Fail gracefully

Resources#

What is React? | Mosh
What is React?

Typescript#

If you're new to TypeScript and want to learn. TypeScript Deep Dive is a fantastic resource.

Typescript encourages a more declarative style of programming through things like interfaces and static typing. Writing a strongly typed code enhances readability, reduces bugs and it improves debugging.

  • Don't use any - consider unknown if you don't know the type

  • Use named exports over default exports - We want to be explicit and consistent with our naming and default exports do not specify the name to be used by consumers of the module

  • Include types for 3rd party libraries

    • If it isn't available, condsider an alternative, or follow this guide here
  • Use objects for frontend-packages function parameters. This allows you to add optional arguments without resulting in a breaking change.

  • Only throw instances of Error. This allows for proper stack traces and makes your application considerably easier to debug. Do not throw objects that do not extend Error.

Interfaces and Types#

  • Use an interface
    • to describes a contract that something can adhere to
    • when you want extends or implements e.g
interface Foo {
foo: string;
}
interface FooBar extends Foo {
bar: string;
}
class X implements FooBar {
foo: string;
bar: string;
}
  • Use a type
    • to describes what something is
    • when you might need a union or intersection e.g
type Foo = number | { someProperty: number };
  • Use PascalCase for name.
  • Don't prefix names with I - It is unconventional. lib.d.ts defines important interfaces without an I (e.g. Window, Document etc).
  • Use camelCase for members.

Bad

interface IFoo {
Name: string;
DayOfWeek: string;
}

Good

interface Foo {
name: string;
dayOfWeek: string;
}

Resources#

Last updated on by Garrett Smith