
This guide is to show you how to create a new React app with Vite and configure it with Biome, lint-staged, commitlint and husky to maintain code consistency.
REQUIREMENTS
Manual installation - STEP-BY-STEP GUIDE
-
Clone an empty repository to your local machine and open your terminal or command prompt.
-
Run the following command to create a new React app using Vite template with TypeScript:
pnpm create vite --template react-ts
- Install
vite-tsconfig-pathspackage to enable path aliases:
pnpm add -D vite-tsconfig-paths
- Open the
tsconfig.jsonfile and replace it with the following configurations:
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
- Open
vite.config.tsfile in the project root directory and update it with the following configurations:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), tsconfigPaths()],
});
- Install
Biome:
pnpm add -D @biomejs/biome
- Open the
package.jsonfile and add the following scripts:
"scripts": {
...
"lint": "biome lint ."
}
- Open (or create if not existing) the
biome.jsonfile in the project root directory and update it with the following configurations:
{
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"domains": {
"react": "recommended"
},
"includes": ["**/src/**", "!**/src/stories"],
"rules": {
"recommended": true,
"nursery": {
"useSortedClasses": {
"fix": "safe",
"level": "error",
"options": {
"functions": ["cn", "clsx", "twMerge", "cva"]
}
}
},
"style": {
"useConsistentCurlyBraces": "error",
"useBlockStatements": "off",
"useExportType": "error",
"noNonNullAssertion": "off"
},
"correctness": {
"useExhaustiveDependencies": "warn",
"noUnusedImports": "error",
"noUnusedVariables": "error",
"noInvalidUseBeforeDeclaration": "error"
},
"suspicious": {
"noExplicitAny": "error",
"useAwait": "error",
"noConsole": "warn",
"noDebugger": "error",
"noEmptyBlockStatements": "error",
"noVar": "error",
"noArrayIndexKey": "warn"
},
"a11y": {
"noSvgWithoutTitle": "off",
"useKeyWithClickEvents": "off",
"noStaticElementInteractions": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "es5",
"semicolons": "always",
"indentStyle": "space",
"indentWidth": 2
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": {
"level": "on",
"options": {
"groups": [
":PACKAGE:",
":BLANK_LINE:",
[
"@/components/**",
"@/constants/**",
"@/hooks/**",
"@/interfaces/**",
"@/layouts/**",
"@/lib/**",
"@/pages/**",
"@/services/**",
"@/stores/**",
"@/utils/**"
],
":BLANK_LINE:",
["@/assets/**"],
":BLANK_LINE:",
["./**"]
]
}
}
}
}
}
}
- Open the
tsconfig.app.jsonfile in the project root directory and update it with the following configurations:
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"]
}
- Create a folder called
.vscodeat root of the current directory, and create asettings.jsonand update it with following configurations:
{
"editor.formatOnSave": true,
"tailwindCSS.classFunctions": ["cn", "clsx", "twMerge", "cva"],
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit",
"source.fixAll.biome": "explicit"
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome"
},
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
- Install
husky,commitlintandlint-stagedpackages:
pnpm add -D husky @commitlint/{cli,config-conventional} lint-staged
- Initialize
husky:
pnpm exec husky init && pnpm i
- Set up the
pre-commithook:
echo "npx lint-staged" > .husky/pre-commit
echo "npx --no -- commitlint --edit ${1}" > .husky/commit-msg
- Create a
.lintstagedrc.jsonfile in the project root directory and add the following configurations:
{
"*.{ts,tsx,js}": ["pnpm lint"]
}
- Create a
.commitlintrc.jsonfile in the project root directory and add the following configurations:
{ "extends": ["@commitlint/config-conventional"] }
- Create the necessary folders for your coding template:
cd src && mkdir components constants hooks interfaces layouts pages services stores utils
⚠️ Warning
You MIGHT need to RESTART your IDE to have these above configurations applied.
Once you have followed these steps, you will have a React app set up with Vite and additional configurations for Biome, Husky, commitlint and lint-staged. You can now start developing your application by adding code to the respective folders.