Skip to content

Contributor Guide

Christina Ahrens Roberts edited this page Oct 17, 2022 · 45 revisions

Table of Contents

TL;DR

You might start by checking out this welcome slide show and the other contents of this Google Drive folder.

Libraries and Technologies

  1. React
  2. react-hyperscript-helpers
  3. Lodash/fp
  4. CircleCI
  5. yarn
  6. create-react-app / react-scripts

Our Coding Philosophy

We would like our contributors to understand the principles behind our code base. With this information we hope to make it easier for you to contribute and understand why we have made certain decisions in our code. As you read through the document you should see these philosophies emerge in our coding style and practices.

  1. Write simple code: clear, concise and easy to understand

    • Simple does not mean easy, solutions to difficult problems can be coded with simplicity
    • This is difficult to do in practice, but we always strive for simple code
    • Beware of clever solutions that are hard to understand
  2. Ask: why / what is the problem we are addressing?

    • Does it bring value to the user?
    • More features is not always better
    • Just because we can do something, does that mean we should? Is it the right thing to do?
    • Are we solving an issue for the user, or just completing a prescribed task?
    • Making sure we understand the problem as a whole, pushing back and getting clarification when it is not clearly understood
  3. Strike a balance between following standard patterns and thinking outside the box

    • Is something hard to understand? Can it be done better? Do it! This keeps tech debt down, the code base simple, easy to understand and work with.
    • Standards can be a great place to start and may be the best answer
    • Accepted or industry standard approaches have value and get us close to where we want to be, rethinking problems from first principles can spur innovation and deliver better results
    • The world around us is constantly changing and new solutions can present themselves when rethinking a problem
    • We accept this within our own codebase as well. If the rationale for doing something no longer holds, be willing to change it. "That is how we have always done it" is not a good rationale
  4. Be willing to give and receive feedback

    • Being able to give and receive feedback is an excellent way to improve your skills as an individual and support the project
  5. Usability and Accessibility are a high priority

    • Ensure our application is accessible so everyone can use it
    • Accessible applications tend to be more usable for all
    • Accessible pages are easier to test
    • Test how the users will interact with the application
  6. Mentoring is an integral part of becoming a better engineer

    • The ability to explain and answer questions demonstrates greater understanding and exposes areas where you can improve
    • Ask questions! This helps you and the person explaining the answer solidify knowledge and exposes areas of confusion.
      • Don't be afraid to ask the same question multiple times, that is part of learning
  7. Keep the development environment simple so the developer experience is painless

    • Use tools that keep the environment simple and straightforward to use
    • Provide clear error messages where appropriate

Coding Style

  1. We use react-hyperscript-helpers rather than JSX to keep our code base cleaner

    • Hyperscript helpers allows developers to remain in a javascript context rather than having to make a mental context switch to an XML templating language while developing
  2. Use Lodash/fp for data transformation and functional utility

    • fp is the functional programming variant of Lodash designed for better composability, with immutability and auto currying built in
    • This allows us to keep the data simple and not tie the data or shape of the data directly into our UI components
    • We generally prefer Lodash utilities over native functions
  3. Use function instead of class components

    • Function components better support our functional coding style
    • Use React hooks instead of lifecycle methods in a function component
      • If you need more custom behavior look at the code base for our custom hooks
      • All custom hooks will be prefixed with "use" (e.g. useOnMount)
  4. Reduce the amount of state in your functions and components - what is the minimum state needed?

    • Don't save derived state: retain a single source of truth
  5. We style our components directly using the style prop

    • This keeps the styling close to the code allowing developers to easily add styles without having to switch contexts to CSS or another file
    • This also prevents developers from having to deal with CSS classes and side effects of the cascade
  6. Be sure any components you add to the page have the appropriate aria-labels and keyboard accessibility

  7. Destructure values down to the most atomic property in most cases

  8. Be mindful when using conditionals

    • Use reasonable default values when appropriate rather than using imperative code or conditionals
    • We use short circuit evaluation for conditionals with a boolean result
  9. Prefer const over var or let

    • Re-assignable variables introduce additional state and potentially side effects into a function. This can make it difficult to reason about the code and potentially introduce bugs
  10. Lint your code using the ESLint rule set

    • Using an eslint plugin with your IDE will improve your developer experience while working with the codebase

Coding Practices

  1. Keeping code simple is easier said than done.

    • Some general thoughts on simplicity to take into account when contributing code

      • Could someone else explain your code?
      • In a year from now will you still understand this code?
      • Did you have to use comments to clarify your code, or is it self explanatory?
      • Do your functions and components need to know implementation details of other functions and components?
      • Is the data decoupled sufficiently from the logic?
    • Concepts that can make your code simpler

      • Ensure functions and components are single purpose
      • Avoid side effects
      • When you need to deal with side effects, use the right abstractions to make it clear we are dealing with a side effect (e.g. useEffect)
      • Make use of small, simple helper functions
      • Keep functions pure
      • Utilize our existing constructs (e.g. withErrorHandling instead of try/catch)
    • Concepts that will add complexity to your code

      • Adding a lot of state
      • Sharing state across components
      • Excessive branching / conditionals
      • Adding special cases
      • Using abstractions that are too powerful for the intended result
        • e.g. using a sledgehammer to hang a picture
      • Premature optimizations
  2. Favor functional, declarative coding

    • Functional code that is side-effect free or has predictable effects is easier to reason about and test
    • This helps us keeping data separate from the application logic
    • We prefer composable constructs such as wrappers (e.g. withErrorHandling) as opposed to imperative code
    • When the need for imperative code arises, make sure the coding style is clearly imperative (use if/else rather than ternary expressions)
    • Take advantage of currying where you can
  3. Understand the problem

    • Before writing code, it is good to understand what value the change is bringing to the user
    • It is also good to understand the user flow - how the user uses the application - to make sure we are providing the correct functionality rather than just prescribed functionality
      • For example, a user may request making a data column wider so they can more easily copy and paste data
      • Diving deeper and asking why they want to copy data in the first place may yield more information, unveiling what the user actually wants vs. what they asked for
  4. Feedback

    • We prefer slowing down and iterating several times on a PR to ensure the code is right and in line with our standards rather than quickly pushing code through
    • We emphasize a high level of code quality in our codebase to prevent technical debt and keep the application easy to develop
    • We encourage comments and discussion in PR's to release high quality, understandable code
    • To merge the code with our dev branch, at least 1 PR approval from a member of the Saturn team is needed
  5. Do not be afraid to change existing code to make it easier to work with

    • If you find yourself trying to work around existing code think about what improvements could be made to it rather then continuing on the workaround
    • Feel free to reach out to any member of the team if you are unsure of how to proceed before investing too much time into a solution - we love to help our contributors!
  6. Release often

    • Once code is merged to dev, it is considered production ready and deployable
    • We release every weekday. Once you have merged your code it will be live in production around 11:00AM
    • A frequent release cycle helps us to keep our deployment process simple which allows us to rapidly fix issues as they arise

Accessibility

When writing and reviewing PRs, remember to check your interface for accessibility. Here is a list of common issues that you should check (note that this is certainly not an exhaustive list):

  1. Color contrast meets WCAG standards
  2. Color is not the sole indication of state or information
  3. All input elements have labels
  4. All interactive elements are keyboard focusable with a logical tab order (try interacting with your interface without the mouse!)
  5. Your HTML is semantic or has the proper aria roles defined
  6. All images have the alt attribute present (if image is only decorative, use empty string for value)
  7. Headings are used logically in descending order (H1, H2, H3, etc.)

There are several static analysis tools that you can use to catch many of the common issues. Note that axe is enabled by default in development mode, so if you open the JavaScript console while running Terra locally you will see accessibility errors/warnings as you navigate Terra. Here are links to other options/plugins that can be run on demand in any environment:

  1. axe Dev Tools
  2. ANDI
  3. Lighthouse, built into Chrome dev tools

If you have the time, try using VoiceOver (on Mac) to check if your page is understandable and usable with a screen reader. Screen reader resources:

  1. Screen reader Questions and Answers
  2. Using VoiceOver

General Accessibility Training/Resources:

  1. W3C Introduction to Web Accessibility Course
  2. WebAIM Introduction to Accessibility
  3. Accessibility Overview by Mark Sadecki
  4. WCAG 2 Standards
  5. Tutorial that covers basic concepts with simple exercises

Automated testing options (automated testing can catch about half of all accessibility issues):

  1. Integration tests can call verifyAccessibility to check for accessibility errors anywhere on the current page. This will verify color contrast of enabled items, among catching other issues that can be statically detected.
  2. Unit tests that render components can use toHaveNoViolations to look for accessibility issues in the rendered component. Note that color contrast cannot be verified with this type of test, as the component rendered in a virtual DOM.

Visual Design Notes

This section is a work in progress. We will add notes on visual design preferences as questions come up from contributors.

  1. Minimum width
    • The application has a minimum width defined in the style.css file. This width was determined from the real world screen sizes we were seeing from users of the app.

Other Resources

Simple Made Easy - Rich Hickey

Clone this wiki locally