{"id":24932602,"url":"https://github.com/linhnguyen-gt/new-react-native","last_synced_at":"2025-04-09T22:42:56.540Z","repository":{"id":259854925,"uuid":"836231558","full_name":"linhnguyen-gt/new-react-native","owner":"linhnguyen-gt","description":"✨ Best practice redux build with react native","archived":false,"fork":false,"pushed_at":"2025-03-18T13:04:57.000Z","size":2862,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-18T14:23:07.462Z","etag":null,"topics":["hooks","react-native","redux","redux-saga","redux-toolkit","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linhnguyen-gt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-31T12:22:05.000Z","updated_at":"2025-03-18T13:05:21.000Z","dependencies_parsed_at":"2025-03-11T07:26:53.348Z","dependency_job_id":"56719f21-695b-4f09-9294-596a7fbdf8d6","html_url":"https://github.com/linhnguyen-gt/new-react-native","commit_stats":null,"previous_names":["linhnguyen-gt/new-react-native"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhnguyen-gt%2Fnew-react-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhnguyen-gt%2Fnew-react-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhnguyen-gt%2Fnew-react-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhnguyen-gt%2Fnew-react-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linhnguyen-gt","download_url":"https://codeload.github.com/linhnguyen-gt/new-react-native/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248124951,"owners_count":21051758,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hooks","react-native","redux","redux-saga","redux-toolkit","typescript"],"created_at":"2025-02-02T14:49:55.984Z","updated_at":"2025-04-09T22:42:56.531Z","avatar_url":"https://github.com/linhnguyen-gt.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e🚀 New React Native Project\u003c/h1\u003e\n  \u003cp\u003eA powerful React Native boilerplate with production-ready configurations and best practices\u003c/p\u003e\n\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://reactnative.dev/\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/React_Native-v0.77.0-blue?style=for-the-badge\u0026logo=react\u0026logoColor=white\" alt=\"react-native\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.typescriptlang.org/\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/TypeScript-v5.5.4-blue?style=for-the-badge\u0026logo=typescript\u0026logoColor=white\" alt=\"typescript\" /\u003e\n    \u003c/a\u003e\n  \u003c/p\u003e\n\n### Core Libraries\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Expo-v52.0.38-000020?style=for-the-badge\u0026logo=expo\u0026logoColor=white\" alt=\"expo\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Gluestack_UI-v1.1.71-1B1B1F?style=for-the-badge\" alt=\"gluestack\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/React_Navigation-v7.0.15-6B52AE?style=for-the-badge\u0026logo=react\u0026logoColor=white\" alt=\"react-navigation\" /\u003e\n  \u003c/p\u003e\n\n### State Management \u0026 API\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Redux_Toolkit-v2.6.1-764ABC?style=for-the-badge\u0026logo=redux\u0026logoColor=white\" alt=\"redux\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Redux_Saga-v1.3.0-89D96D?style=for-the-badge\u0026logo=redux-saga\u0026logoColor=white\" alt=\"redux-saga\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Axios-v1.8.3-5A29E4?style=for-the-badge\u0026logo=axios\u0026logoColor=white\" alt=\"axios\" /\u003e\n  \u003c/p\u003e\n\n### UI \u0026 Styling\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/NativeWind-v4.1.23-38BDF8?style=for-the-badge\u0026logo=tailwindcss\u0026logoColor=white\" alt=\"nativewind\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Tailwind_CSS-v3.4.17-38B2AC?style=for-the-badge\u0026logo=tailwind-css\u0026logoColor=white\" alt=\"tailwindcss\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/React_Native_Vector_Icons-v10.2.0-4B32C3?style=for-the-badge\" alt=\"vector-icons\" /\u003e\n  \u003c/p\u003e\n\n### Form \u0026 Validation\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Formik-v2.4.6-0744AE?style=for-the-badge\" alt=\"formik\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Yup-v1.6.1-32CD32?style=for-the-badge\" alt=\"yup\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Zod-v3.24.2-3068B7?style=for-the-badge\" alt=\"zod\" /\u003e\n  \u003c/p\u003e\n\n### Development \u0026 Testing\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESLint-v8.19.0-4B32C3?style=for-the-badge\u0026logo=eslint\u0026logoColor=white\" alt=\"eslint\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Prettier-v3.3.3-F7B93E?style=for-the-badge\u0026logo=prettier\u0026logoColor=black\" alt=\"prettier\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Jest-v29.7.0-C21325?style=for-the-badge\u0026logo=jest\u0026logoColor=white\" alt=\"jest\" /\u003e\n  \u003c/p\u003e\n\n### Environment \u0026 Storage\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Dotenv-v16.4.7-ECD53F?style=for-the-badge\u0026logo=dotenv\u0026logoColor=black\" alt=\"dotenv\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Async_Storage-v2.1.2-3B82F6?style=for-the-badge\" alt=\"async-storage\" /\u003e\n  \u003c/p\u003e\n\n### Development Tools\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Reactotron-v5.1.12-7B61FF?style=for-the-badge\" alt=\"reactotron\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/React_Native_Reanimated-v3.17.1-FF4154?style=for-the-badge\" alt=\"reanimated\" /\u003e\n  \u003c/p\u003e\n\n### Environment Support\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/iOS-000000?style=for-the-badge\u0026logo=apple\u0026logoColor=white\" alt=\"ios\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Android-3DDC84?style=for-the-badge\u0026logo=android\u0026logoColor=white\" alt=\"android\" /\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n## ✨ Features\n\n- 🏗️ Built with TypeScript for type safety\n- 📱 Cross-platform (iOS \u0026 Android) support\n- 🔄 Redux + Redux Saga for state management\n- 🎨 NativeWind for styling with Tailwind CSS\n- 🛠️ Reactotron integration for debugging\n- 🌐 Multi-environment support (Development, Staging, Production)\n- 📦 Pre-configured folder structure\n- 🔍 ESLint + Prettier for code quality\n- 🎯 Gluestack UI components\n- 🔐 Environment-specific configurations\n\n## 🚀 Quick Start\n\n### Prerequisites\n\nMake sure you have the following installed:\n\n- Node.js (v20+)\n- Yarn\n- React Native CLI\n- Xcode (for iOS)\n- Android Studio (for Android)\n- Ruby (\u003e= 2.6.10)\n- CocoaPods\n\n### Installation\n\n### Clone the repository\\*\\*\n\n```bash\ngit clone https://github.com/linhnguyen-gt/new-react-native\ncd new-react-native\n```\n\n## 🔧 Environment Configuration\n\n### Setup New Environment\n\nFirst, you need to run the environment setup script:\n\n```bash\n# Using npm\nnpm run env:setup\n\n# Using yarn\nyarn env:setup\n```\n\nThis script will:\n\n1. Set up dotenv-vault (optional)\n2. Create environment files for all environments:\n    - `.env` (Development environment)\n    - `.env.staging` (Staging environment)\n    - `.env.production` (Production environment)\n3. Configure necessary environment variables\n\n### Environment Files Structure\n\nEach environment file contains:\n\n```bash\n# Required Variables\nAPP_FLAVOR=development|staging|production\nVERSION_CODE=1\nVERSION_NAME=1.0.0\nAPI_URL=https://api.example.com\n\n# Optional Variables (configured during setup)\nGOOGLE_API_KEY=\nFACEBOOK_APP_ID=\n# ... other variables\n```\n\n### Using Different Environments\n\n```bash\n# Development (default)\nyarn android\nyarn ios\n\n# Staging\nyarn android:stg\nyarn ios:stg\n\n# Production\nyarn android:pro\nyarn ios:pro\n```\n\n### Setup Steps for New Project\n\n### iOS Configuration\n\n1. **Podfile Configuration**\n   Add this configuration block to your Podfile:\n\n```ruby\n# Configuration name environment mapping\nproject 'NewReactNative', {\n    'Debug' =\u003e :debug,\n    'Dev.Debug' =\u003e :debug,\n    'Dev.Release' =\u003e :release,\n    'Release' =\u003e :release,\n    'Staging.Debug' =\u003e :debug,\n    'Staging.Release' =\u003e :release,\n    'Product.Debug' =\u003e :debug,\n    'Product.Release' =\u003e :release\n}\n```\n\nThis configuration:\n\n- Maps each build configuration to its corresponding mode (:debug or :release)\n- Supports all environments (Dev, Staging, Product)\n- Enables both Debug and Release builds for each environment\n\n2. **Build Configurations**\n   Xcode should have these configurations set up:\n\n- Staging.Debug/Release (Staging)\n- Product.Debug/Release (Production)\n- Debug/Release (Default)\n\n3. **Version Management Script**\n   Add this script to Build Phase in Xcode:\n\n.xcode.env.\n\n```bash\n# Determine APP_ENV based on CONFIGURATION\nif [[ \"${CONFIGURATION}\" == *\"Product\"* ]]; then\n    export APP_ENV=\"production\"\nelif [[ \"${CONFIGURATION}\" == *\"Staging\"* ]]; then\n    export APP_ENV=\"staging\"\nfi\n```\n\nBuild Phases -\u003e Add Run Script -\u003e Paste\n\n```bash\n# Get the environment from configuration name\necho \"Debug: Raw CONFIGURATION value: ${CONFIGURATION}\"\n\nif [[ \"${CONFIGURATION}\" == *\"Product\"* ]]; then\n  ENV_FILE=\"${SRCROOT}/../.env.production\"\n  echo \"Debug: Matched Product configuration\"\nelif [[ \"${CONFIGURATION}\" == *\"Staging\"* ]]; then\n  ENV_FILE=\"${SRCROOT}/../.env.staging\"\n  echo \"Debug: Matched Staging configuration\"\nelse\n  ENV_FILE=\"${SRCROOT}/../.env\"\n  echo \"Debug: Using default configuration\"\nfi\n\n# Ensure INFOPLIST_FILE is set\nif [ -z \"$INFOPLIST_FILE\" ]; then\n    echo \"Error: INFOPLIST_FILE not set\"\n    exit 0\nfi\n\nINFO_PLIST=\"${SRCROOT}/${INFOPLIST_FILE}\"\n\necho \"=== Environment Setup ===\"\necho \"CONFIGURATION: ${CONFIGURATION}\"\necho \"Using env file: ${ENV_FILE}\"\necho \"Info.plist path: ${INFO_PLIST}\"\n\n# Default values in case env file is missing\nVERSION_CODE=\"1\"\nVERSION_NAME=\"1.0.0\"\n\n# Try to read from env file if it exists\nif [ -f \"$ENV_FILE\" ]; then\n    echo \"Reading from env file...\"\n\n    # Read VERSION_CODE\n    VERSION_CODE_LINE=$(grep \"^VERSION_CODE=\" \"$ENV_FILE\" || echo \"\")\n    if [ ! -z \"$VERSION_CODE_LINE\" ]; then\n        VERSION_CODE=$(echo \"$VERSION_CODE_LINE\" | cut -d'=' -f2 | tr -d '\"' | tr -d ' ')\n    fi\n\n    # Read VERSION_NAME\n    VERSION_NAME_LINE=$(grep \"^VERSION_NAME=\" \"$ENV_FILE\" || echo \"\")\n    if [ ! -z \"$VERSION_NAME_LINE\" ]; then\n        VERSION_NAME=$(echo \"$VERSION_NAME_LINE\" | cut -d'=' -f2 | tr -d '\"' | tr -d ' ')\n    fi\nelse\n    echo \"Warning: Environment file not found, using default values\"\nfi\n\necho \"Using versions - Code: $VERSION_CODE, Name: $VERSION_NAME\"\n\n# Update Info.plist if it exists\nif [ -f \"$INFO_PLIST\" ]; then\n    echo \"Updating Info.plist...\"\n    /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION_CODE\" \"$INFO_PLIST\" || true\n    /usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $VERSION_NAME\" \"$INFO_PLIST\" || true\n    echo \"Info.plist update completed\"\nelse\n    echo \"Warning: Info.plist not found at $INFO_PLIST\"\nfi\n```\n\n4. **Setup Steps for iOS**\n\n- Copy the configuration block to your Podfile\n- Run `pod install` to apply configurations\n- Set up corresponding Build Configurations in Xcode\n- Add the version management script to Build Phases\n- Configure schemes to use appropriate configurations\n\n### Android Configuration\n\n1. **Product Flavors**\n   Add to app/build.gradle:\n\n```gradle\n    flavorDimensions 'default'\n    productFlavors {\n        dev {\n            dimension 'default'\n            applicationId 'com.newreactnative'\n            resValue 'string', 'build_config_package', 'com.newreactnative'\n\n            def envFile = new File(\"${project.rootDir.parentFile}/.env\")\n            if (envFile.exists()) {\n                def versionProps = getVersionFromEnv(envFile)\n                versionCode versionProps.code.toInteger()\n                versionName versionProps.name\n            }\n        }\n\n        staging {\n            dimension 'default'\n            applicationId 'com.newreactnative.stg'\n            resValue 'string', 'build_config_package', 'com.newreactnative'\n\n            def envFile = new File(\"${project.rootDir.parentFile}/.env.staging\")\n            if (envFile.exists()) {\n                def versionProps = getVersionFromEnv(envFile)\n                versionCode versionProps.code.toInteger()\n                versionName versionProps.name\n            }\n        }\n        production {\n            dimension 'default'\n            applicationId 'com.newreactnative.production'\n            resValue 'string', 'build_config_package', 'com.newreactnative'\n\n            def envFile = new File(\"${project.rootDir.parentFile}/.env.production\")\n            if (envFile.exists()) {\n                def versionProps = getVersionFromEnv(envFile)\n                versionCode versionProps.code.toInteger()\n                versionName versionProps.name\n            }\n        }\n    }\n\ndef getVersionFromEnv(File envFile) {\n    def versionCode = \"1\"\n    def versionName = \"1.0.0\"\n\n    envFile.eachLine { line -\u003e\n        if (line.contains('=')) {\n            def (key, value) = line.split('=', 2)\n            if (key == \"VERSION_CODE\") versionCode = value?.trim()?.replaceAll('\"', '')\n            if (key == \"VERSION_NAME\") versionName = value?.trim()?.replaceAll('\"', '')\n        }\n    }\n\n    println \"Reading from ${envFile.path}\"\n    println \"VERSION_CODE: ${versionCode}\"\n    println \"VERSION_NAME: ${versionName}\"\n\n    return [code: versionCode, name: versionName]\n}\n```\n\n### Update package.json Scripts\n\n```json\n{\n    \"scripts\": {\n        \"android\": \"npx expo run:android --variant devDebug --app-id com.newreactnative\",\n        \"android:stg\": \"APP_ENV=staging \u0026\u0026 npx expo run:android --variant stagingDebug --app-id com.newreactnative.stg\",\n        \"android:pro\": \"APP_ENV=production \u0026\u0026 npx expo run:android --variant productionDebug --app-id com.newreactnative.production\",\n        \"ios\": \"npx expo run:ios\",\n        \"ios:stg\": \"APP_ENV=staging npx expo run:ios --scheme Staging --configuration Staging.Debug\",\n        \"ios:pro\": \"APP_ENV=production npx expo run:ios --scheme Pro --configuration Product.Debug\"\n    }\n}\n```\n\n### Update .gitignore\n\n```bash\n.env*\n.flaskenv*\n!.env.project\n!.env.vault\n# Environment files\n.env\n.env.*\n!.env.example\n!.env.vault\n```\n\n### Version Management\n\nThe setup automatically manages app versions based on environment files:\n\n- VERSION_CODE: Used for internal build numbering\n- VERSION_NAME: Used for display version in stores\n\n### Important Notes\n\n- Never commit `.env` files to git (they are automatically added to .gitignore)\n- Always commit `.env.example` and `.env.vault` (if using dotenv-vault)\n- Share vault credentials with your team members if using dotenv-vault\n\n## 📁 Project Structure\n\n```\nsrc/\n├── App.tsx          # Main App component\n├── Root.tsx         # Root component with Redux Provider\n├── apis/            # API integration\n├── components/      # Reusable UI components\n├── constants/       # Constants Keys\n├── enums/           # TypeScript enums\n├── helper/          # Helper functions\n├── hooks/           # Custom React hooks\n├── models/          # Models related to API\n└── redux/           # Redux store configuration\n    ├── actions/     # Redux actions\n    ├── reducers/    # Redux reducers\n    ├── sagas/       # Redux sagas\n    └── selectors/   # Redux selectors\n├── screens/         # Screen components\n├── services/        # Business logic and services\n    └── reactotron/  # Reactotron configuration\n    └── navigation/  # Navigation configuration\n    └── httpClient/  # Base API client configuration\n└── store/           # Redux store configuration\n└── types/           # TypeScript types\n\n```\n\n## 🛠️ Development Tools\n\n### Reactotron\n\nFor debugging, the project includes Reactotron integration. To use it:\n\n1. Install Reactotron on your development machine\n2. Run the following command for Android:\n\n```bash\nyarn adb:reactotron\n```\n\n## 📝 Code Style\n\nThe project uses ESLint and Prettier for code formatting. Run linting with:\n\n```bash\nyarn lint # Check for issues\n```\n\nTo fix linting errors automatically, use:\n\n```bash\nyarn lint:fix # Fix automatic issues\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinhnguyen-gt%2Fnew-react-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinhnguyen-gt%2Fnew-react-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinhnguyen-gt%2Fnew-react-native/lists"}