DEV Community

Suman Bhattarai
Suman Bhattarai

Posted on

πŸš€ Enhancing Your React Native Codebase: Best Practices & Modern Tooling

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:

  1. Install dependencies:
   npm install --save-dev prettier
Enter fullscreen mode Exit fullscreen mode
  1. Create a .prettierrc configuration file:
   {
     "semi": true,
     "singleQuote": true,
     "trailingComma": "all",
     "printWidth": 80
   }
Enter fullscreen mode Exit fullscreen mode
  1. Add a script to your package.json:
   "scripts": {
     "format": "prettier --write \"**/*.{js,jsx,ts,tsx}\""
   }
Enter fullscreen mode Exit fullscreen mode
  1. Run the following command to format all files:
   npm run format
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ 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:

  1. Install TypeScript and necessary types:
   npm install --save-dev typescript @types/react @types/react-native
Enter fullscreen mode Exit fullscreen mode
  1. 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"]
   }
Enter fullscreen mode Exit fullscreen mode
  1. 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>
);
Enter fullscreen mode Exit fullscreen mode

🚨 3. Linting with ESLint

ESLint identifies problematic patterns in your code. For TypeScript projects, combine it with @typescript-eslint.

πŸ› οΈ Configuration:

  1. Install dependencies:
   npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-native
Enter fullscreen mode Exit fullscreen mode
  1. 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' },
     },
   };
Enter fullscreen mode Exit fullscreen mode
  1. Add a lint script:
   "scripts": {
     "lint": "eslint \"**/*.{js,jsx,ts,tsx}\""
   }
Enter fullscreen mode Exit fullscreen mode

πŸ—οΈ 4. Clean Imports with Module Resolver

Avoid messy relative paths like ../../../components/Button using babel-plugin-module-resolver.

πŸ”§ Setup:

  1. Install the plugin:
   npm install --save-dev babel-plugin-module-resolver
Enter fullscreen mode Exit fullscreen mode
  1. Update babel.config.js:
   module.exports = {
     plugins: [
       [
         'module-resolver',
         {
           root: ['./src'],
           alias: {
             '@components': './src/components',
             '@utils': './src/utils',
           },
         },
       ],
     ],
   };
Enter fullscreen mode Exit fullscreen mode
  1. Update tsconfig.json:
   {
     "compilerOptions": {
       "baseUrl": "./src",
       "paths": {
         "@components/*": ["components/*"],
         "@utils/*": ["utils/*"]
       }
     }
   }
Enter fullscreen mode Exit fullscreen mode
  1. Use clean imports:
   import Button from '@components/Button';
Enter fullscreen mode Exit fullscreen mode

πŸ€– 5. Automate Workflows with Git Hooks

Enforce code quality pre-commit with Husky and lint-staged.

πŸš€ Setup:

  1. Install dependencies:
   npm install --save-dev husky lint-staged
Enter fullscreen mode Exit fullscreen mode
  1. Configure Husky in package.json:
   "scripts": {
     "prepare": "husky install"
   },
   "lint-staged": {
     "**/*.{js,jsx,ts,tsx}": [
       "eslint --fix",
       "prettier --write",
       "git add"
     ]
   }
Enter fullscreen mode Exit fullscreen mode
  1. Create a pre-commit hook:
   npx husky add .husky/pre-commit "npx lint-staged"
Enter fullscreen mode Exit fullscreen mode

πŸ† Additional Best Practices

πŸ“ A. Directory Structure

Organize files by feature or domain:

assets/
src/
  β”œβ”€β”€ components/
  β”œβ”€β”€ screens/
  β”œβ”€β”€ utils/
  β”œβ”€β”€ hooks/
  └── store/
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ B. Testing

Add Jest for unit tests and Detox for E2E testing:

npm install --save-dev jest @testing-library/react-native detox
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ 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! πŸš€

Top comments (0)