1. Vấn đề thực tế Khi phát triển song song một ứng dụng web và một ứng dụng di động, nhóm thường gặp phải việc lặp lại code xử lý nghiệp vụ (validation, gọi API, quản lý trạng thái cục bộ). Việc copy‑paste dẫn đến sai lệch khi sửa đổi, tăng chi phí bảo trì và khó kiểm thử. 2. Giải pháp: Monorepo + Thư viện chung - Sử dụng công cụ như Nx, Turborepo hoặc Yarn Workspaces để quản lý nhiều package trong một repo. - Tách các custom hook, service, utility thành một package nội bộ (ví dụ: @myorg/core). - Cả hai app (web, native) đều cài đặt package này như một dependency nội bộ, đảm bảo cùng một phiên bản logic. 3. Cấu trúc thư mục mẫu - apps/web – dự án Next.js / Vite React. - apps/mobile – dự án Expo / React Native CLI. - packages/core – chứa hooks (useAuth, useCart), services (apiClient), constants, types TypeScript. - packages/ui – component chia sẻ (Button, Input) nếu cần giao diện thống nhất. 4. Ví dụ custom hook dùng chung ```ts // packages/core/src/hooks/useFetchUser.ts export const useFetchUser = (id: string) => { const [data, setData] = useState<User | null>(null); const [loading, setLoading] = useState(true); useEffect(() => { apiClient.get<User>(`/users/${id}`) .then(res => setData(res.data)) .finally(() => setLoading(false)); }, [id]); return { data, loading }; }; ``` Cả web lẫn mobile chỉ cần `import { useFetchUser } from '@myorg/core/hooks';`. 5. Lợi ích cụ thể - Đảm bảo logic nghiệp vụ luôn đồng bộ giữa hai nền tảng. - Giảm dung lượng bundle vì code chung chỉ được build một lần. - Dễ dàng viết unit test cho core một lần, chạy cho cả hai app. - Khi cần thay đổi quy tắc validation, chỉ sửa ở một chỗ. 6. Lưu ý khi triển khai - Đặt phiên bản package core theo semantic versioning; cập nhật phụ thuộc trong apps qua `yarn workspace @myorg/web add @myorg/core@latest`. - Tránh import trực tiếp module native (ví dụ: `react-native`) trong core; hãy dùng abstraction hoặc platform‑specific file (`*.web.ts`, `*.native.ts`). - Cấu hình TypeScript path mapping để IDE hiểu alias `@myorg/core`. 7. Kết luận Việc tập trung logic vào một package chung trong monorepo giúp nhóm phát triển nhanh hơn, ít bug hơn và dễ mở rộng khi thêm nền tảng mới (desktop, TV). Hãy bắt đầu bằng việc tách một hook nhỏ, sau đó mở rộng dần sang toàn bộ domain logic.