npm

npm is a node package manager that install and update node packages

  • Build config and dependencies management file is package.json
  • npm : command to install packages or run scripts from the local node_modules or package.json
    • npm install <packageName> : install the package into the local node_modules folder and adds it to the package.json
      • Use npm install --save-dev <packageName> to save the package as a devDependencies
    • npm run <script> : run the scripts specified in the local package.json
    • npm list <packageName> : list the all versions of the package installed inside the project and any of its dependencies
  • npx : executes a package without permanently installing it
    • npx use the latest CLI version of the package
    • Use when installing/update expo and react packages to pull compatible versions
  • Dependencies versions are writen as <major>.<minor>.<patch> so 19.1.2 has major = 19, minor = 1, and patch = 2
    • ^ Caret allow MINOR and PATCH updates
    • ~ Tilde only allow PATCH updates
    • No symbol means exact version
  • Standard Fields of npm:
    • dependencies include the packages the app need to run; always included in build and deploy
    • devDependencies development-only dependencies; tools for testing your app, but will be excluded in production build
    • peerDependencies tells that the included packages need to be install to be able to use the current package; primarily used when making your own library/ package
    • overrides the included dependencies will override all others globally

TurboRepo

TurboRepo is a monorepo tool for managing multiple projects/packages in a single repository.

  • Documentation: turborepo.com/
  • It handles task running and caching
  • Can enforce dependencies on projects to make sure all versions match
  • Good for sharing codes between related projects and tightly coupled apps (frontend & backend)
  • turbo.json : TurboRepo config file
  • // Sample turbo.json setup
    {
      "$schema": "https://turbo.build/schema.json",
      "globalDependencies": ["shared/**"],
      "tasks": {
        "dev": {
          "cache": false,
          "persistent": true
        },
        "build": {
          "dependsOn": ["^build"],
          "outputs": [".next/**", "dist/**"]
        },
        "lint": {
          "outputs": []
        },
        "clean": {
          "cache": false
        }
      }
    }
  • package.json : the main file that manages the repo
  • // Sample package.json for TurboRepo
    {
      "name": "monorepo-setup",
      "private": true,
      "packageManager": "npm@10.9.3",
      "scripts": {
        "dev": "turbo run dev --parallel",
        "dev:web": "turbo run dev --filter=web",
        "dev:mobile": "turbo run dev --filter=mobile",
        "clean": "turbo run clean",
        "build": "turbo run build",
        "lint": "eslint . --ext .js,.mjs,.cjs,.jsx,.ts,.tsx",
        "lint:web": "eslint app --ext .js,.jsx,.ts,.tsx",
        "lint:mobile": "eslint mobile --ext .js,.jsx,.ts,.tsx"
      },
      "devDependencies": {
        "@eslint/js": "^9.34.0",
        "eslint": "^9.34.0",
        "eslint-plugin-react": "^7.37.5",
        "globals": "^16.3.0",
        "turbo": "^2.5.6"
      },
      "workspaces": {
        "packages": [
          "apps/*",
          "shared/*"
        ]
      },
      "dependencies": {
        "react": "19.0.0",
        "react-dom": "19.0.0",
        "react-native": "0.79.6"
      },
      "overrides": {
        "react": "19.0.0",
        "react-dom": "19.0.0",
        "react-native": "0.79.6"
      }
    }

ESLint

  • eslint : Useful to check syntax and other problems with the code before compilation
    1. npm install --save-dev eslint
    2. npx eslint --init
  • Install the VS Code extension to lint project in real time. link
  • Sample eslint.config.mjs file
  • // eslint.config.mjs file
    import js from "@eslint/js";
    import globals from "globals";
    import pluginReact from "eslint-plugin-react";
    import pluginTS from "@typescript-eslint/eslint-plugin";
    import pluginReactNative from "eslint-plugin-react-native";
    import { defineConfig } from "eslint/config";
    
    export default defineConfig([
      // JS / JSX files
      {
        files: ["**/*.{js,mjs,cjs,jsx}"],
        plugins: { js },
        extends: ["js/recommended"],
        languageOptions: { globals: { ...globals.browser, ...globals.node } },
      },
    
      // TypeScript / TSX files
      {
        files: ["**/*.{ts,tsx}"],
        plugins: { "@typescript-eslint": pluginTS },
        extends: ["plugin:@typescript-eslint/recommended"],
      },
    
      // React rules (web + mobile)
      pluginReact.configs.flat.recommended,
    
      // React Native rules
      pluginReactNative.configs.recommended,
    
      // Ignore common build folders
      {
        ignores: ["node_modules/**", "app/.next/**", "mobile/.expo/**", "dist/**"],
      },
    ]);

Other Useful Packages

  • babel-plugin-module-resolver : allows any projects to use import alias like Next.js jsconfig.js; rewrite paths during compilation
    • npm install --save-dev babel-plugin-module-resolver
    • Use inside a babel.config.js file
    • // Sample babel.config.js inside Expo app
      module.exports = {
        presets: ["babel-preset-expo"],
        plugins: [
          [
            "module-resolver",
            {
              alias: {
                "@shared": ["../../shared"],
                "@mobileAssets": ["./assets"]
              },
            },
          ],
        ],
      };