Table of Contents
- Prerequisites
- Initial Setup
- ESLint Configuration
- Prettier Setup
- Husky and Git Hooks
- Testing Setup
- TypeScript Configuration
- Babel Configuration
- Security Setup
- Troubleshooting
Prerequisites
Before starting, ensure you have:
- Node.js (v18 or higher)
- Yarn package manager
- Git installed
- A React Native project (new or existing)
Initial Setup
1. Install Required Dependencies
# Core dependencies
yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier
yarn add -D husky lint-staged
yarn add -D jest @testing-library/react-native @testing-library/jest-native
yarn add -D typescript @types/react @types/react-native
yarn add -D babel-plugin-module-resolver
2. Create Configuration Files
Create the following files in your project root:
touch .eslintrc.json
touch .prettierrc
touch .prettierignore
touch jest.config.js
touch jest-setup.ts
touch tsconfig.json
touch babel.config.js
ESLint Configuration
1. Basic ESLint Setup
Create .eslintrc.json
:
{
"env": {
"browser": true,
"es2021": true,
"react-native/react-native": true,
"jest": true
},
"extends": [
"plugin:react/recommended",
"airbnb",
"airbnb/hooks",
"plugin:@typescript-eslint/recommended",
"plugin:import/typescript",
"plugin:import/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"react",
"react-native",
"@typescript-eslint",
"import",
"prettier",
"react-hooks"
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
"project": "./tsconfig.json"
},
"settings": {
"import/resolver": {
"babel-module": {
"root": ["./src"],
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"alias": {
"@": "./src"
}
}
}
},
"rules": {
"react/function-component-definition": [
"error",
{
"namedComponents": "arrow-function",
"unnamedComponents": "arrow-function"
}
],
"react/prop-types": "off",
"react/jsx-props-no-spreading": "off",
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
"react/require-default-props": "off",
"react/react-in-jsx-scope": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
],
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
}
}
2. Add ESLint Scripts to package.json
{
"scripts": {
"lint": "eslint .",
"lintFixAll": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix"
}
}
3. Install Additional ESLint Plugins
yarn add -D eslint-plugin-react
yarn add -D eslint-plugin-react-native
yarn add -D eslint-plugin-react-hooks
yarn add -D eslint-plugin-import
Prettier Setup
1. Create .prettierrc
{
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "avoid"
}
2. Create .prettierignore
node_modules/
build/
coverage/
ios/
android/
*.md
3. Add Prettier Scripts
{
"scripts": {
"prettierFixAll": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
"fix:lintPrettier": "yarn prettierFixAll && yarn lintFixAll"
}
}
Husky and Git Hooks
1. Initialize Husky
# Initialize husky
yarn husky init
# Install pre-commit hook
yarn husky add .husky/pre-commit "yarn lint-staged"
2. Configure lint-staged
Add to package.json:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
3. Add Husky Scripts
{
"scripts": {
"prepare": "husky"
}
}
Testing Setup
1. Configure Jest
Create jest.config.js
:
module.exports = {
preset: 'react-native',
setupFiles: ['./jest-setup.ts'],
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|@react-navigation)/)',
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
testRegex: '(/__tests__/.*|(\.|/)(test|spec))\.[jt]sx?$',
moduleNameMapper: {
'\.svg': '<rootDir>/__mocks__/svgMock.js',
'^@/(.*)$': '<rootDir>/src/$1'
},
collectCoverage: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/*.stories.{ts,tsx}',
],
};
2. Create Jest Setup File
Create jest-setup.ts
:
import '@testing-library/jest-native/extend-expect';
// Mock react-native-reanimated
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
Reanimated.default.call = () => {};
return Reanimated;
});
// Mock react-native-gesture-handler
jest.mock('react-native-gesture-handler', () => {
const View = require('react-native/Libraries/Components/View/View');
return {
Swipeable: View,
DrawerLayout: View,
State: {},
ScrollView: View,
Slider: View,
Switch: View,
TextInput: View,
ToolbarAndroid: View,
ViewPagerAndroid: View,
DrawerLayoutAndroid: View,
WebView: View,
NativeViewGestureHandler: View,
TapGestureHandler: View,
FlingGestureHandler: View,
ForceTouchGestureHandler: View,
LongPressGestureHandler: View,
PanGestureHandler: View,
PinchGestureHandler: View,
RotationGestureHandler: View,
};
});
3. Add Test Scripts
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}
TypeScript Configuration
1. Configure TypeScript
Create tsconfig.json
:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": ["es2017"],
"allowJs": true,
"jsx": "react-native",
"noEmit": true,
"isolatedModules": true,
"strict": true,
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
},
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}
Babel Configuration
1. Configure Babel
Create babel.config.js
:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src'],
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
alias: {
'@': './src',
'@components': './src/components',
'@screens': './src/screens',
'@navigation': './src/navigation',
'@services': './src/services',
'@store': './src/store',
'@utils': './src/utils',
'@hooks': './src/hooks',
'@types': './src/types',
},
},
],
],
};
Security Setup
1. Install GitLeaks
# For macOS
brew install gitleaks
# For Linux
snap install gitleaks
2. Add GitLeaks Script
{
"scripts": {
"gitleaks": "git diff --staged | gitleaks detect -v --pipe"
}
}
Troubleshooting
Common Issues and Solutions
- ESLint Errors
# Clear ESLint cache
yarn eslint --cache --cache-location .eslintcache .
- TypeScript Errors
# Clear TypeScript cache
rm -rf node_modules/.cache/typescript/
- Jest Issues
# Clear Jest cache
yarn jest --clearCache
- Husky Not Working
# Reinstall husky
yarn remove husky
yarn add -D husky
yarn husky init
VS Code Integration
Add to .vscode/settings.json
:
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"typescript.tsdk": "node_modules/typescript/lib"
}
Best Practices
- Commit Messages
feat: add new feature
fix: resolve bug
docs: update documentation
style: format code
refactor: restructure code
test: add tests
chore: update dependencies
- File Organization
src/
├── components/
├── screens/
├── navigation/
├── services/
├── store/
├── utils/
├── hooks/
└── types/
- Testing Structure
__tests__/
├── components/
├── screens/
├── utils/
└── __mocks__/
Conclusion
This comprehensive setup provides a solid foundation for maintaining code quality in React Native projects. The combination of ESLint, Prettier, Husky, and Jest ensures consistent code style, prevents common mistakes, and maintains high code quality standards.
Remember to:
- Run
yarn install
after adding new dependencies - Commit your changes after setting up each tool
- Update your team’s documentation with these standards
- Regularly update dependencies to their latest stable versions