Frontend
As mentioned in the domain section of the docs the web app will be built with React. But just like any other application we need to choose an architectural pattern to base our folder structure and workflow around, and also designate code styles, plus sanity checks (baked into the developer experience).
For further information to the chosen architecture pattern please head to UI Folder Structure Patterns |
Setup
The project was generated with vite
. Using the command:
-
pnpm create vite@latest kakeibro-web
(Select React > Typescript + SWC) -
pnpm install
Formatter and Linter
Because vite
follows best practices and modern web development practices, it
already comes with eslint integrated, and its auto-generated README
also has instructions
on how to extend the configuration so that we get a richer dev experience with the linter.
The formatter will be prettier
, however, we are not going to leverage multiple
libraries running on their own, mostly because there are conflicts with eslint most of
the time, however, due to this fact, eslint has a specific plugin that helps bridging
its own rules with prettier (plus leveraging the package on its backend). Hence we
will install eslint’s prettier integration:
pnpm i --D eslint-plugin-prettier eslint-config-prettier
pnpm i --D --E prettier
Just so that we stick to one prettier version without it dragging into new versions that
might break our project we use --save-exact
or --E
. And because all of these libraries
are solely for dev purposes we will install them as dev dependencies --save-dev
or -D
Once this is done it’s advisable to set your IDE to use ESLint as its default formatter, (as we mentioned before, with the prettier plugin it will leverage prettier as the code formatter on the backend).

Figure 1. VS Code Example
In case there are other plugins such as prettier, standardjs, etc installed it is advisable to have them disabled on the project’s workspace due to our philosophy of leveraging all of these tools as packages and through configuration files that allow for all of the setup to be transferable across all developers, we don’t want for IDE plugins with their own set of rules to interfere. The only plugin that should be leveraged to get intellisense, code fixes, and other things through the IDE’s plugin reading our config files and packages should be ESLint

Figure 2. VS Code Extensions Disabled for Workspace
In the case of VS Code, the moment we establish configurations for the workspace
such as the default formatter a |
This project specifically works with ESLint’s Flat Config configuration. Which is the new ESLint way of configuring things, and so, the plugin on the IDE should be set to follow this:

Figure 3. ESLint Flat Config
It’s worth noting that both |
With that in mind, the settings.json
that’s at .vscode
should look something like
this:
{
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": { (1)
"source.fixAll.eslint": "explicit" (2)
},
"eslint.useFlatConfig": true,
}
1 | This is key, we are sort of configuring a macro that when hitting the Save key on the IDE we are running "something". |
2 | In our case we want to run eslint and fix all errors that it might encounter,
it used to be true , but there’s a warning stating that it will be deprecated for the
explicit value. |
Once that’s configured everytime we hit Save
, then eslint (integrated with prettier)
should run and fix as much errors and warnings it might highlight (and of course follow
any prettier rules that are also enforced).
Here’s the breakdown of the configurations that were setup:
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import eslintPrettier from "eslint-plugin-prettier"; (1)
export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: { (2)
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname,
},
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
prettier: eslintPrettier, (3)
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"prettier/prettier": [ (4)
"error", (5)
{ (6)
semi: true,
trailingComma: "es5",
singleQuote: true,
printWidth: 80,
endOfLine: "auto",
singleAttributePerLine: false,
},
],
},
},
);
1 | Notice how we are importing a named property from the plugin package we installed. |
2 | This section was added following the guide that’s stated at the autogenerated README
file from vite. |
3 | We declare as a plugin the eslint-prettier we imported in <1> so that it’s applied
to the eslint pipeline. |
4 | And we can know configure the specific prettier plugin format through this key. |
5 | We are configuring so that any errors that prettier finds are highlighted as errors from eslint’s side. |
6 | And lastly this is the prettier configuration that we can customize how we see fit. |