1 - Enterprise-Ready React Setup: Vite, ESLint, Prettier, and VS Code Essentials


<HelloWorld!>
Building a full-stack application without using proper structure or best practices can quickly lead to chaos. In this guide, I’ll walk you through how to organize and set up a project like an enterprise-level application, making the development process smoother. While the setup might feel tedious at first, it will ultimately save you and your team significant time and effort.
Before we continue, make sure you have Node.js, Git, and Visual Studio Code installed on your PC. These are the building blocks of our project. Make sure to install them from their official websites.
First, you will have to open Visual Studio Code, You will see something like this:
On the sidebar, click on the Tetris-like icon (the 5th icon in this image). This is where all the extensions for Visual Studio Code are located. That said, I will give you a set of extensions to install, which will greatly help you during your development process. They are as follows:
Docker (by Microsoft): Provides an integrated experience for developing, managing, and deploying containerized applications using Docker. (We will learn more about this in my future articles)
ESLint (by Microsoft): Automatically checks your code for errors and style issues
Prettier – Code formatter (by Prettier): Formats your code to keep it clean and consistent.
MongoDB for VS Code (by MongoDB): Connect to and manage MongoDB databases from VS Code. (This is also an interesting topic, we will discuss this in future articles too.)
Once installed, you can use it in all your future projects; no need to do it every time you open Visual Studio Code (VS Code). Next, need to create a folder in VS Code that will contain all documents and files of our project. Let’s call it the Setup Project.
We are going to use Vite to set up our project—a popular and rapid way to start a React(Frontend) project. This is how it is done in 6 simple steps:
In the VS Code menu bar, go to Terminal → New Terminal to open a new Terminal.
Inside the Terminal, run the following command:
$ npm create vite@latest .
Make sure there is a period at the end of the command to create the project in the current folder instead of creating a new folder. You do not need to force this command into your head, just see it as, “I am asking npm to create me a Vite application **@**nd make sure it is the latest version”. You can replace the date with the name of your project if you wish.
Vite will ask you a name for the project, you choose whatever suits you, then for the Framework, for now, we will work with React, and finally, the variant which will be JavaScript.
Now our project is set up, we can run the following in your VS Code terminal to install all the dependencies:
$ npm install
We should be able to test if your project is running properly. Run:
$ npm run dev
In the Terminal, you will see a URL telling you where your app is running. You can either hold Ctrl (Cmd on macOS) and click on the link to open it in your browser, or manually enter the URL in a browser.
Finally, we have something that works 🤧. We can give ourselves a pat on the back and move on. ✨
Setting up ESLint and Prettier to enforce best practices and code style
Remember when we installed the ESLint and Prettier extensions? Now it's time to dive deeper and integrate them into our project setup.
We are first going to install the necessary dependencies using npm. In the Terminal, click on the Split Terminal icon at the top right of the Terminal pane to create a new Terminal pane. This will keep our app running while we run other commands.
Run the following command in your terminal:
npm install --save-dev prettier@3.1.0 eslint@8.54.0 eslint-plugin-react@7.33.2 eslint-config-prettier@9.0.0 eslint-plugin-jsx-a11y@6.8.0
The packages installed are the following:
Prettier: Automatically formats our code.
ESLint: Checks our code and suggests improvements.
eslint-plugin-react: Adds React-specific rules to ESLint.
eslint-config-prettier: Turns off style rules in ESLint so Prettier can take over.
eslint-plugin-jsx-a11y: Helps catch accessibility issues in JSX.
The most focused of you have noticed that this time, in the command, we have included “—save-dev” instead of simply installing the packages normally.
--save-dev
It tells npm to install the package only for development, not for production use. Since they will just be used to ease our development in VS Code, they will have no use in production. This is important to keep the size of our containers as small as possible later.Okay, great job so far! We have installed the depencies needed for our setup, let us move to the configuration of Prettier.
As we said earlier, Prettier will format the code for us and replace the default code formatter for JavaScript in VS Code. It will allow us to spend more time writing code, automatically formatting it for us properly when we save the file. Follow these steps to configure Prettier:
Right-click below the files list in the left sidebar of VS Code (if it is not opened, click the Files icon) and press New file... to create a new file. Call it .prettierrc.json (do not forget the period at the beginning of the file name!).
The newly created file should open automatically, so we can start writing the following configuration into it. We first create a new object and type in the following:
{ "trailingComma": "all", "tabWidth": 2, "printWidth": 80, "semi": false, "jsxSingleQuote": true, "singleQuote": true }
No, don’t worry, let me explain what is going on✨:
trailingComma: "all"
➤ It adds commas at the end of objects or arrays, even the last item.Example:
const obj = { name: "Chris", age: 18, };
tabWidth: 2
➤ It tells Prettier to use 2 spaces when indenting your code, instead of 4 or a tab.printWidth: 80
➤ If a line of code gets longer than 80 characters, Prettier will break it into multiple lines to make it more readable.semi: false
➤ It tells Prettier not to add semicolons (;) at the end of lines unless really needed.jsxSingleQuote: true
➤ In JSX (used in React), it uses single quotes ('
) instead of double quotes ("
).Example:
<div class='box'></div>
singleQuote: true
➤ In JavaScript, use single quotes for strings instead of double quotes.Example:
const name = 'Remy';
There is more to be added, but this is okay for you to see prettier in action.
We are done with the configuration of Prettier, but VS Code doesn’t know that we want to format our code as per the given parameters. This is done as follows:
Open the VS Code settings by going to File | Preferences... | Settings on Windows/Linux, or Code | Settings... | Settings on macOS.
In the newly opened settings editor, click on the Workspace tab. This ensures that we save all our settings in a .vscode/settings.json file in our project folder. When other developers open our project, they will automatically be using those settings as well.
Search for “Editor: format on save” and check the checkbox to enable formatting code on save.
Search for “Editor default formatter” and select Prettier - Code formatter from the list.
To verify that Prettier works, open the .prettierrc.json file, add some extra spaces to the beginning of a line, and save the file. You should notice that Prettier reformatted the code to adhere to the defined code style. It will reduce the number of spaces for indentation to two.
Now that Prettier is set up properly, we do not need to worry about formatting our code manually anymore. Feel free to just type in code as you go and save the file to get it formatted for you!
To improve performance and avoid running Prettier on files that should not be automatically formatted, we can ignore certain files and folders by creating a Prettier ignore file. Follow these steps:
Create a new file called .prettierignore in the root of our project, similar to how we created the .prettierrc.json file.
Add the following contents to it to ignore the transpiled source code:
dist/
Now that we have successfully set up Prettier, we are going to configure ESLint to enforce coding best practices.
Configuring ESLint
While Prettier focuses on the style and formatting of our code, ESLint focuses on the actual code, avoiding common mistakes or unnecessary code. Let’s configure it now:
Delete the automatically created .eslintrc.cjs file.
Create a new .eslintrc.json file and start writing the following configuration into it. First, we set root to true to make sure ESLint does not look at parent folders for more configuration:
{ "root": true, "env": { "browser": true }, "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:react/jsx-runtime", "plugin:jsx-a11y/recommended", "prettier" ], "settings": { "react": { "version": "detect" } }, "overrides": [ { "files": ["*.js", "*.jsx"] } ] }
Explanation:
root: true
➤ It tells ESLint to treat this configuration as the main one and not to search for other config files in parent folders.
env: { browser: true }
➤ Enables browser global variables like
window
,document
, etc., so ESLint won’t flag them as errors.parserOptions: { ecmaVersion: "latest", sourceType: "module" }
➤
ecmaVersion: "latest"
means use the latest JavaScript features.
➤sourceType: "module"
tells ESLint that your code usesimport
andexport
(ES Modules).-extends: [ "eslint:recommended", "plugin:react/recommended", "plugin:react/jsx-runtime", "plugin:jsx-a11y/recommended", "prettier" ]
➤
eslint:recommended
: Adds core ESLint rules that help avoid bugs.plugin:react/recommended
: Adds recommended React-specific rules.plugin:react/jsx-runtime
: Supports JSX without needing to import React (React 17+).plugin:jsx-a11y/recommended
: Adds accessibility rules for better HTML in React.prettier
: Turns off ESLint rules that conflict with Prettier’s formatting.
settings: { react: { version: "detect" } }
➤ Automatically detects the installed version of React so ESLint can apply the right rules.
overrides: [ { files: [".js", ".jsx"] } ]
➤ ESLint will only check files that end in
.js
or.jsx
.
The same way as we did with prettier, we can also add create an .eslintignore file with the following content:
dist/
vite.config.js
Save the files and run npx eslint src in the Terminal to run the linter. You will see that there are some errors already due to our configured rules not matching the source provided by the default project in Vite:
Fortunately, all these issues are automatically fixable by ESLint. Run npx eslint src --fix to fix the issues automatically. Now, when you run npx eslint src again, you will not get any output. This means that there were no linter errors!
Adding a new script to run our linter
In the previous section, we have been calling the linter by running npx eslint src manually. We are now going to add a lint script to package.json:
In the Terminal, run the following command to define a lint script in the package.json file: $
npm pkg set scripts.lint="eslint src"
You can see this as, “We're asking
npm
to set thescripts.lint
property inpackage.json
(which we call pkg) to the valueeslint src
.”Now, run
npm run lint
in the Terminal. This should execute eslint src successfully, just likenpx eslint src
did:After setting up ESLint and Prettier, we still need to make sure that they run before we commit code. Let’s set up Husky to make sure we commit proper code now
Setting up Husky to make sure we commit proper code
Once Prettier and ESLint are configured, our code will be automatically formatted when we save, and any mistakes or ignored best practices will be flagged by ESLint in VS Code. Still, some issues might slip through and get committed by accident. To prevent this, we can use Husky and lint-staged to run Prettier and ESLint before each Git commit, making sure the code is properly formatted and linted beforehand.
Let’s set Husky and lint-staged up by following these steps:
Run the following command to install Husky and lint-staged as dev dependencies:
$ npm install --save-dev husky@8.0.3 lint-staged@15.1.0
Open the package.json file and add the following lint-staged configuration to it in a new object after devDependencies, then save the file. This will run Prettier and ESlint on all committed .js and .jsx files and attempt to automatically fix code style and linter errors, if possible:
"lint-staged": { "**/*.{js,jsx}": [ "npx prettier --write", "npx eslint --fix" ] }
Initialize a Git repository and make an initial commit with just the package. json file, as lint-staged does not get executed on the initial commit:
$ git init
$ git add package.json
$ git commit -m "chore: initial commit"
Add the husky install script to a prepare script in package.json, so that Husky gets installed automatically when the project is cloned and npm install is executed:
$ npm pkg set scripts.prepare="husky install"
Since we do not need to run npm install again right now, we need to manually run the prepare script this time:
$ npm run prepare
Add a pre-commit hook for lint-staged, so that ESLint and Prettier run every time we do git commit:
$ npx husky add .husky/pre-commit "npx lint-staged"
Now, add all files to Git and attempt to make a commit:
$ git add .
$ git commit -m "chore: basic project setup"
If everything worked successfully, you should see husky running lint-staged, which, in turn, runs prettier and eslint, after you run git commit. If you are getting a configuration error, ensure that all files are saved properly and then run git commit again.
Setting up commitlint to enforce a standard for our commit messages
Besides checking our code with linters, we can also validate our commit messages. You might have seen that we’ve been starting our commit messages with a type—like chore. These types help clarify the purpose of each commit. To ensure that commit messages consistently follow this format, we can configure commitlint. Here’s how to set it up:
Install commitlint and a conventional config for commitlint:
$ npm install --save-dev @commitlint/cli@18.4.3 @commitlint/config-conventional@18.4.3
Create a new .commitlintrc.json file in the root of our project and add the following contents:
{ "extends": ["@commitlint/config-conventional"] }
Add a commit-msg hook to Husky:
$ npx husky add .husky/commit-msg 'npx commitlint --edit "$1"'
Now, if we try adding our changed files and committing without a type or a wrong type, we will get an error from commitlint and will not be able to make such a commit. If we add the correct type, it will succeed:
$ git add .
$ git commit -m "no type"
$ git commit -m "wrong: type"
$ git commit -m "chore: configure commitlint"
The image below demonstrates Husky in action. If we try to commit with an incorrectly formatted message, Husky will block the commit. Only when the commit message follows the correct format will it be accepted and the commit will succeed.
Here's a paraphrased version of your explanation:
Commit messages that follow the Conventional Commits format (as defined at conventionalcommits.org) start with a type, optionally include a scope, and end with a description—formatted as:type(scope): description
.
The type helps clarify the purpose of the change. Here are the commonly used types:
fix
: Fixes a bugfeat
: Introduces a new featurerefactor
: Changes the code structure without adding features or fixing bugsbuild
: Modifies the build process or external dependenciesci
: Updates to CI/CD configurationdocs
: Documentation-only changesperf
: Performance improvementsstyle
: Code formatting updates (no logic changes)test
: Adds or modifies tests
The scope (which is optional) is especially helpful in monorepos, as it identifies which specific app or library the commit affects.
By setting up your React project with Vite, ESLint, Prettier, and VS Code configurations from the start, you're laying a solid foundation for clean, consistent, and scalable code. Whether you're building solo projects or collaborating in a team, this setup ensures you're writing code that's easier to read, debug, and maintain. Now that your environment is ready, you're equipped to focus on what truly matters—building great user experiences✨.
</HelloWorld!>
Subscribe to my newsletter
Read articles from Remy Christophe Tuyishime Hirwa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
