Skip to main content

react-native-monorepo-config

Configures React Native projects in monorepo environments using npm/yarn workspaces, Metro bundler, shared packages, and cross-platform module resolution.

Aller à l'installation

Informations de source

Dépôt
paulpas/agent-skill-router
Dernière activité de la source
9 juin 2026 à 16:28
Langue détectée de SKILL.md
anglais
Étoiles
4
Forks
1

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
react-native-monorepo-config
description
Configures React Native projects in monorepo environments using npm/yarn workspaces, Metro bundler, shared packages, and cross-platform module resolution.
license
MIT
compatibility
opencode
archetypes
["tactical","generation"]
anti_triggers
["brainstorming","vague ideation","long-form architecture"]
response_profile
{"verbosity":"low","directive_strength":"high","abstraction_level":"operational"}
metadata
{"version":"1.0.0","domain":"coding","triggers":"react native monorepo, metro config, yarn workspaces, shared packages, react native config, monorepo setup, cross-platform","role":"implementation","scope":"implementation","output-format":"code","content-types":["code","guidance","do-dont","examples","config"],"related-skills":"react-native-state-management, react-native-rendering","author":"https://github.com/vercel-labs","source":"https://github.com/vercel-labs/agent-skills"}
# React Native Monorepo Configuration A senior build engineer who configures React Native projects within monorepo workspaces — wiring Metro bundler to watch all packages, resolving modules across workspace boundaries, linking native modules, and sharing TypeScript/ESLint/Prettier configs across application and library packages. ## TL;DR Checklist - [ ] Initialize with npm or yarn workspaces pointing to `apps/*` and `packages/*` - [ ] Configure Metro's `watchFolders` to include all workspace package directories - [ ] Set `nodeModulesPaths` / `moduleDirs` for cross-workspace module resolution - [ ] Create `react-native.config.js` for native module linking across packages - [ ] Add `.watchmanconfig` to the monorepo root for proper file watching - [ ] Use BlockList in metro.config.js to exclude large generated directories (node_modules, build) - [ ] Share TypeScript config via `extends` pattern across all packages - [ ] Configure Jest with `projects` for per-package test configuration --- ## When to Use Use this skill when: - Setting up a new React Native app inside an existing monorepo with shared packages - Migrating a standalone React Native app into a monorepo with npm/yarn workspaces - Adding a shared UI component library that must work across iOS and Android - Configuring Metro to resolve modules from sibling packages in a workspaces setup - Debugging "module not found" errors in a React Native monorepo - Standardizing TypeScript, ESLint, and Prettier across multiple React Native packages --- ## When NOT to Use Avoid this skill for: - Standalone React Native apps outside a monorepo — the default Metro config suffices - Expo-managed workflows (bare workflow may still need this) — Expo's built-in monorepo support handles most cases - Pure web monorepos without React Native — different bundling tools (webpack, Vite) are involved - Prototyping where monorepo overhead is not yet justified --- ## Core Workflow 1. **Initialize Workspaces** — Create the monorepo root with workspace configuration: - Use `yarn workspaces` (more mature monorepo support) or `npm workspaces` - Structure packages as `apps/*` (applications) and `packages/*` (shared libraries) - Set `"private": true` at root with `"workspaces"` config **Checkpoint:** Run `yarn install` — verify packages link correctly in `node_modules`. 2. **Configure Metro** — The critical step for React Native monorepos: - Add all workspace package directories to `watchFolders` - Configure `nodeModulesPaths` to resolve modules across workspaces - Add BlockList patterns for `node_modules` outside workspace packages - Set `projectRoot` explicitly to avoid ambiguity **Checkpoint:** Run `npx react-native start` — Metro must bundle without "module not found" errors. 3. **Set Up Native Module Linking** — Bridge React Native packages across workspaces: - Create `react-native.config.js` in app packages to declare dependencies - Configure `dependency.platforms` for iOS (podspec path) and Android (gradle link) - Run `pod install` in the iOS directory to link native pods **Checkpoint:** Verify native modules (camera, maps, gestures) build on both platforms. 4. **Share Configuration** — Unify tooling across packages: - Create `packages/config/` with shared `tsconfig.json`, `.eslintrc.js`, `.prettierrc.js` - App and library packages extend these with `extends: '../../packages/config/tsconfig.json'` - Share Jest config with `jest.config.base.js` and per-package overrides **Checkpoint:** Run `tsc --noEmit` and `eslint .` from root — both must pass with shared configs. 5. **Configure File Watching** — Ensure monorepo file changes trigger Metro rebuilds: - Add `.watchmanconfig` with `{}` at the monorepo root - Ensure `watchman` is installed and version >= 2022.02.14.00 - Add `watchFolders` to Metro config for all symlinked package directories **Checkpoint:** Make a change in a shared package and verify Metro triggers a rebuild. --- ## Implementation Patterns ### Pattern 1: Root Workspace Config ```json // ❌ BAD: Missing private: true, no workspaces config, flat node_modules { "name": "my-app", "version": "1.0.0" } // ✅ GOOD: Proper workspaces config with app and package directories { "name": "my-monorepo", "version": "1.0.0", "private": true, "workspaces": [ "apps/*", "packages/*" ], "scripts": { "android": "yarn workspace @my/app android", "ios": "yarn workspace @my/app ios", "start": "yarn workspace @my/app start", "lint": "eslint . --ext .ts,.tsx", "typecheck": "tsc --noEmit --pretty", "test": "jest" }, "devDependencies": { "typescript": "^5.4.0", "eslint": "^8.57.0", "prettier": "^3.2.0", "jest": "^29.7.0" } } ``` ### Pattern 2: Metro Configuration for Monorepo ```javascript // metro.config.js (at apps/my-app/) const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); const workspaceRoot = path.resolve(__dirname, '../..'); const appRoot = __dirname; /** * Metro configuration for React Native monorepo. * * watchFolders: tells Metro to monitor all workspace package directories. * nodeModulesPaths: resolves require('module') across workspace boundaries. * blockList: prevents Metro from crawling large extraneous directories. */ const config = { projectRoot: appRoot, watchFolders: [ workspaceRoot, // Explicitly add shared package directories so Metro watches them path.resolve(workspaceRoot, 'packages/shared-ui'), path.resolve(workspaceRoot, 'packages/config'), path.resolve(workspaceRoot, 'packages/helpers'), ], resolver: { nodeModulesPaths: [ // Resolve modules from the app's node_modules first, then hoisted root path.resolve(appRoot, 'node_modules'), path.resolve(workspaceRoot, 'node_modules'), ], // Prevent Metro from crawling every node_modules in every workspace blockList: [ /.*\/node_modules\/.*\/node_modules\/.*/, /.*\/__pycache__\/.*/, /.*\/\.git\/.*/, /.*\/build\/.*/, /.*\/\.expo\/.*/, ], // Ensure sourceExts covers shared package file types sourceExts: ['js', 'jsx', 'ts', 'tsx', 'json', 'svg'], }, transformer: { // Required for monorepo symlinks minifierConfig: { keep_classnames: true, keep_fnames: true, }, }, }; module.exports = mergeConfig(getDefaultConfig(appRoot), config); ``` ### Pattern 3: Native Module Linking ```javascript // ❌ BAD: No react-native.config.js — native modules in workspace packages won't link // (metro cannot resolve native modules from symlinked packages without this config) // ✅ GOOD: react-native.config.js at the app level declares workspace dependency linkage // apps/my-app/react-native.config.js module.exports = { project: { ios: { sourceDir: './ios', }, android: { sourceDir: './android', }, }, dependencies: { // Map workspace packages to their native module locations '@my/shared-ui': { root: path.resolve(__dirname, '../../packages/shared-ui'), platforms: { ios: { podspecPath: path.resolve( __dirname, '../../packages/shared-ui/ios/SharedUI.podspec' ), }, android: { sourceDir: path.resolve( __dirname, '../../packages/shared-ui/android' ), }, }, }, }, }; // ✅ GOOD: Workspace package declares its native module in package.json // packages/shared-ui/package.json { "name": "@my/shared-ui", "version": "1.0.0", "main": "src/index.ts", "react-native": "src/index.ts", "peerDependencies": { "react": "^18.2.0", "react-native": "^0.73.0" }, "publishConfig": { "access": "public" } } ``` ### Pattern 4: Shared TypeScript Config ```json // ❌ BAD: Each package duplicates its own TypeScript config — drifts over time // packages/shared-ui/tsconfig.json { "compilerOptions": { "strict": true, "moduleResolution": "node", "jsx": "react-native", "target": "esnext" } } // apps/my-app/tsconfig.json — same thing copy-pasted { "compilerOptions": { "strict": true, "moduleResolution": "node", "jsx": "react-native", "target": "esnext" } } // ✅ GOOD: Single shared config with per-package overrides // packages/config/tsconfig.base.json { "compilerOptions": { "target": "esnext", "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "react-native", "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "declaration": true, "declarationMap": true, "sourceMap": true, "baseUrl": ".", "paths": { "@my/*": ["packages/*/src"] } }, "exclude": ["node_modules", "build", "dist"] } // packages/shared-ui/tsconfig.json — extends the base { "extends": "../../packages/config/tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDir": "./src" }, "include": ["src"] } // apps/my-app/tsconfig.json — extends the same base { "extends": "../../packages/config/tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDir": "./src" }, "include": ["src"] } ``` ### Pattern 5: Shared ESLint + Prettier Config ```javascript // packages/config/.eslintrc.js module.exports = { root: true, extends: [ '@react-native', 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier', ], plugins: ['@typescript-eslint', 'react', 'react-hooks'], parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 'latest', sourceType: 'module', }, rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'react-native/no-inline-styles': 'error', }, ignorePatterns: ['node_modules', 'build', 'dist', '.expo'], }; // .eslintrc.js at the monorepo root — just points to shared config module.exports = { root: true, extends: ['./packages/config/.eslintrc.js'], }; // packages/config/.prettierrc.js module.exports = { semi: true, trailingComma: 'all', singleQuote: true, printWidth: 100, tabWidth: 2, bracketSpacing: true, arrowParens: 'always', }; // .prettierrc.js at root — delegates to shared config module.exports = { ...require('./packages/config/.prettierrc.js'), }; ``` --- ## Constraints ### MUST DO - Configure Metro's `watchFolders` to include all workspace package directories - Set `nodeModulesPaths` to resolve modules across workspace boundaries - Create `react-native.config.js` in each app package for native module linking - Add `.watchmanconfig` at the monorepo root for reliable file change detection - Share TypeScript, ESLint, and Prettier configs via a central `packages/config` package - Use the `extends` pattern in tsconfig.json to share compilation options - Configure Jest with `projects` or a root config that covers all workspace packages ### MUST NOT DO - Use hoisting settings that break native module resolution — prefer `nohoist` for react-native packages - Forget to add all workspace package paths to Metro's `watchFolders` - Ignore "module not found" errors in CI — they hide broken workspace resolution - Duplicate TypeScript/ESLint/Prettier configs across packages — they will drift - Use npm workspaces without verifying Metro compatibility (yarn workspaces has more mature RN support) - Ignore the `blockList` in Metro config — crawling every nested node_modules causes OOM crashes --- ## Related Skills | Skill | Purpose | |---|---| | `react-native-state-management` | State management library shared across monorepo packages | | `react-native-rendering` | Rendering optimizations shared between app and component library packages | ---
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub