React Native ⚛️ is a powerful framework for building cross-platform mobile apps, but as projects grow, maintaining code quality, scalability, and collaboration becomes challenging. In this guide, we’ll explore tools and strategies to elevate your React Native codebase, including Prettier, TypeScript, ESLint, module resolvers, and more.
✨ 1. Code Formatting with Prettier
Consistent code formatting improves readability and reduces merge conflicts. Prettier automates this process by enforcing a uniform style across your codebase.
🔧 Setup:
- Install dependencies:
npm install --save-dev prettier
- Create a
.prettierrc
configuration file:
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80
}
- Add a script to your
package.json
:
"scripts": {
"format": "prettier --write \"**/*.{js,jsx,ts,tsx}\""
}
- Run the following command to format all files:
npm run format
💡 Pro Tip: Integrate Prettier with your IDE for real-time formatting.
🔒 2. Type Safety with TypeScript
TypeScript catches errors at compile time, provides better autocompletion, and makes refactoring safer.
🚀 Migration Steps:
- Install TypeScript and necessary types:
npm install --save-dev typescript @types/react @types/react-native
- Create a
tsconfig.json
:
{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"jsx": "react-native",
"lib": ["esnext"],
"moduleResolution": "node",
"strict": true,
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"]
}
},
"exclude": ["node_modules"]
}
- Rename
.js
files to.tsx
incrementally and fix type errors.
📌 Example: Typed Component
interface ButtonProps {
title: "string;"
onPress: () => void;
}
const Button = ({ title, onPress }: ButtonProps) => (
<TouchableOpacity onPress={onPress}>
<Text>{title}</Text>
</TouchableOpacity>
);
🚨 3. Linting with ESLint
ESLint identifies problematic patterns in your code. For TypeScript projects, combine it with @typescript-eslint
.
🛠️ Configuration:
- Install dependencies:
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-native
- Create
.eslintrc.js
:
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-native/all',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'react', 'react-native'],
rules: {
'react-native/no-raw-text': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
},
settings: {
react: { version: 'detect' },
},
};
- Add a lint script:
"scripts": {
"lint": "eslint \"**/*.{js,jsx,ts,tsx}\""
}
🏗️ 4. Clean Imports with Module Resolver
Avoid messy relative paths like ../../../components/Button
using babel-plugin-module-resolver
.
🔧 Setup:
- Install the plugin:
npm install --save-dev babel-plugin-module-resolver
- Update
babel.config.js
:
module.exports = {
plugins: [
[
'module-resolver',
{
root: ['./src'],
alias: {
'@components': './src/components',
'@utils': './src/utils',
},
},
],
],
};
- Update
tsconfig.json
:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"],
"@utils/*": ["utils/*"]
}
}
}
- Use clean imports:
import Button from '@components/Button';
🤖 5. Automate Workflows with Git Hooks
Enforce code quality pre-commit with Husky and lint-staged.
🚀 Setup:
- Install dependencies:
npm install --save-dev husky lint-staged
- Configure Husky in
package.json
:
"scripts": {
"prepare": "husky install"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write",
"git add"
]
}
- Create a pre-commit hook:
npx husky add .husky/pre-commit "npx lint-staged"
🏆 Additional Best Practices
📁 A. Directory Structure
Organize files by feature or domain:
assets/
src/
├── components/
├── screens/
├── utils/
├── hooks/
└── store/
🧪 B. Testing
Add Jest for unit tests and Detox for E2E testing:
npm install --save-dev jest @testing-library/react-native detox
🔥 C. Monitoring
Integrate tools like Sentry or Firebase Crashlytics to track runtime errors.
🎯 Conclusion
By integrating these tools and best practices, your React Native codebase becomes:
✅ Consistent with Prettier
✅ Type-safe with TypeScript
✅ Error-resistant with ESLint
✅ Maintainable with module resolvers
✅ Automated via Git hooks
Start incrementally—even small improvements can yield immediate benefits. Over time, these changes will reduce technical debt, streamline collaboration, and make your app more robust. Happy coding! 🚀