10 principles of scalable frontend projects
Tags: engineeringmonday, javascript, architecture, frontend
Published: 2020-03-30 08:38:22

---
title: 10 principles of scalable frontend projects
published: true
description: Core methodologies for building frontend apps with a focus on scalability and maintainability.
tags: engineeringmonday, javascript, architecture, frontend
---

# A common problem
Web apps have come a long way since their initial appearance. We all now know how powerful JavaScript on the web is, and how many endless possibilities exist in terms of framework and technology choices. Different frameworks have their pros and cons, but some core methodologies can be applied to almost every framework. Tools such as create-react-app, next.js, vue-cli, etc., are really helpful for bootstrapping a project and its structure, but after that, you're free to form an application to your preferences and project's requirements. 

I've collected some principles I found valuable when building web applications with **React** and **Vue** that can help you in defining a direction and keeping things tidy and sound. Most of the principles can be applied to all software, but this list is a bit specific to web apps. 


# Principles
1. **Developing components, not screens**
  - try to encapsulate all the logic of a component in isolation, so it can be rendered everywhere with ease, for example, in different screens and sections
  - all the CRUD operations go inside the *controllers / providers* for the data it needs, and that data is passed to *presentational* components
      - one common scenario is redux/vuex - data is persisted to a store and is treated as a single source of truth, and container components extract the relevant data 
2. **Separating presentational and business / controller layer**
  - not all components need to be connected to stores, backend API or some other service
  - by making components "data source agnostic", reusability is greatly increased
3. **Using a standardized way of fetching the data**
  - [rest-hooks](https://resthooks.io/) is a great example of this principle as it encourages a predictable and readable structure for API calls
  - for some projects, using explicit `fetch` calls may be sufficient, but if you're dealing with a lot of resources and relationships, having an abstraction over backend API can be helpful
4. **Having a common user input strategy**
 - forms, select tags, validations, error states all fall into this category
 - UI component libraries such as [antd](https://ant.design/components/form/) provide a solution for this out of the box
 - if you're creating an app without a UI library, consider putting a bit more emphasis on standardizing these elements for better UX
5. **Writing automated tests**
  - components are, in my experience, best tested with integration tests, specifically with [Cypress](https://www.cypress.io/)
  - business logic should be thoroughly covered with unit tests
  - e2e are valuable for smoke testing larger user flows; they can help detect regressions between the client and the API  
6. **Using storybook for creating reusable components**
  - https://storybook.js.org/
  - great way to collaborate with designers and discuss functionality
  - serves as a "living style guide" for your app
7. **Using linters and formatters**
  - examples of linters: ESLint, stylelint
  - most of the bootstrap tools such as create-react-app pre-install linters for you, but if you're on a legacy codebase, they might not be applied
  - they can help you catch bugs, but they can also be used in defining code style for your team — this can help in reducing mental load when developing upon a feature that you've inherited from your colleague
  - [sonarJS eslint plugin](https://github.com/SonarSource/eslint-plugin-sonarjs) can help improve code quality as it checks for logical structure
  - [prettier](https://prettier.io/) is an awesome code formatter that you set up only once, and never think about it again — very useful when working in a team
8. **Avoiding global styles**
  - overrides and resets can be made global
  - CSS modules or CSS-in-JS are some of the technologies that can help in achieving scoped, isolated styles
  - local styles can often lead to better component reusability
9. **Using structured version control** 
  - using a branching model
      - e.g. *[gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)* — "a branching model for Git, created by Vincent Driessen"
      - having a structure in your version control is indispensable for working in a team, but it is helpful even when working on your own
  - linting commit messages - [commitlint](https://commitlint.js.org)
      - useful in creating a changelog and finding bugs as the project develops
      - [angular's commit message rules](https://github.com/angular/angular/blob/master/CONTRIBUTING.md) are often applicable to any software project, and commitlint can help you in keeping those messages consistent with the ruleset
10. **Keeping a changelog**
  - on the beginning of every project, it's usually easy to keep track of all the changes in your mental context
  - as the project grows, the changelog can serve as a central place for discovering notable changes to a codebase, even months and years into development


# The never-ending list
That's all folks! There could surely be many more items added to the list, depending on the project domain and technology, but I find these can improve many frontend apps radically. Almost all of the principles can be applied progressively and by priority defined by you and your team, so no need to worry of applying them all of once. 

What principles do you find *super important* when creating web apps? Share these below in the comments! ⬇️ 

Thanks for reading. 🙏