Blog
Project standards in Umami codebase - Part 1.1

Project standards in Umami codebase - Part 1.1

Inspired by BulletProof React, I applied the codebase architecture concepts to the Umami codebase

Prerequisite

  1. Project standards in Umami codebase — Part 1.0 

In this part 1.1, we review the following project standards in Umami codebase:

  1. ESLint configuration.

  2. Prettier configuration.

  3. Stylelint configuration.

ESLint configuration.

ESLint statically analyzes your code to quickly find problems. It is built into most text editors and you can run ESLint as part of your continuous integration pipeline.

You will find the following code in umami/.eslintrc.json

{
  "env": {
    "browser": true,
    "es2020": true,
    "node": true,
    "jquery": true,
    "jest": true
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 11,
    "sourceType": "module"
  },
  "extends": [
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "eslint:recommended",
    "plugin:prettier/recommended",
    "plugin:import/errors",
    "plugin:import/typescript",
    "plugin:css-modules/recommended",
    "plugin:cypress/recommended",
    "prettier",
    "next"
  ],
  "plugins": ["@typescript-eslint", "prettier", "promise", "css-modules", "cypress"],
  "rules": {
    "no-console": "error",
    "react/display-name": "off",
    "react-hooks/exhaustive-deps": "off",
    "react/react-in-jsx-scope": "off",
    "react/prop-types": "off",
    "import/no-anonymous-default-export": "off",
    "import/no-named-as-default": "off",
    "css-modules/no-unused-class": "off",
    "@next/next/no-img-element": "off",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/no-empty-interface": "off",
    "@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }],
    "@typescript-eslint/no-namespace": ["error", { "allowDeclarations": true }],
    "@typescript-eslint/triple-slash-reference": "off"
  },
  "globals": {
    "React": "writable"
  }
}

Check out the official documentation to learn more about this configuration.

But can you directly copy this configuration and use it in your project? well it depends on your project requirements. For example, you might not need to set the react/display-name to ‘off’ in your project. Start with minimal config and keep adding more rules as you see fit in your project.

There is also umami/.eslintignore

/src/generated/

Although, this approach is deprecated. You can find the latest way of defining ignore rules at https://eslint.org/docs/latest/use/configure/ignore

With the latest approach, you can ignore a directory using the below code:

// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([globalIgnores([".config/*"])]);

Umami’s ESLint setup can serve as a good benchmark for your project configuration.

Prettier configuration.

Prettier is an opinionated code formatter. It supports many languages and integrates with most IDEs. Why? your code is formatted on save. No need to discuss style in code reviews and saves you time and energy

You will find the below prettier configuration in umami/.prettierrc.json

{
  "arrowParens": "avoid",
  "endOfLine": "lf",
  "printWidth": 100,
  "singleQuote": true,
  "trailingComma": "all"
}

You don’t have to argue over single or double quotes ;)

There is also umami/.prettierignore.

/public/script.js
/src/generated/

Stylelint configuration.

Stylelint is a mighty CSS linter that helps you avoid errors and enforce conventions. 

It’s mighty as it:

  • has over 100 built-in rules for modern CSS syntax and features

  • supports plugins so you can create your own custom rules

  • automatically fixes problems where possible

  • supports shareable configs that you can create or extend

  • can be customized to your exact needs

  • has 15k unit tests making it robust

  • is trusted by companies worldwide like Google and GitHub

And it can be extended to:

  • extract embedded styles from HTML, Markdown and CSS-in-JS template literals

  • parse CSS-like languages like SCSS, Sass, Less and SugarSS

Example output:

Learn more about Stylelint.

You will find the below code in umami/.stylelintrc.json.

{
  "extends": ["stylelint-config-recommended", "stylelint-config-css-modules"],
  "rules": {
    "no-descending-specificity": null
  }
}

Umami chose to go with stylelint-config-recommended.

Conclusion:

In the ESLint config, I found this below:

"extends": [
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "eslint:recommended",
    "plugin:prettier/recommended",
    "plugin:import/errors",
    "plugin:import/typescript",
    "plugin:css-modules/recommended",
    "plugin:cypress/recommended",
    "prettier",
    "next"
  ],

Notice how there is recommended extensions used. You will also find this same recommended options in the Stylelint.

"extends": ["stylelint-config-recommended", "stylelint-config-css-modules"],

Except for the css-modules, I would pretty much use this setup in a Next.js project. I would only css-modules extension only if I need it. We see this in Umami because they use css-modules.

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

I spent 200+ hours analyzing Supabase, shadcn/ui, LobeChat. Found the patterns that separate AI slop from production code. Stop refactoring AI slop. Start with proven patterns. Learn how to build production-grade projects.

References:

  1. https://stylelint.io/

  2. https://eslint.org/

  3. https://github.com/umami-software/umami/blob/master/.eslintrc.json

  4. https://eslint.org/docs/latest/use/configure/configuration-files

  5. https://github.com/umami-software/umami/blob/master/.prettierrc.json

  6. https://github.com/umami-software/umami/blob/master/.prettierignore

  7. https://github.com/umami-software/umami/blob/master/.stylelintrc.json

  8. https://prettier.io/