1. 13:01 13/10/2026
Khi xây dựng sản phẩm chạy song song trên web và mobile, việc duy trì giao diện nhất quán là thách thức lớn. Một Design System chia sẻ giúp team tiết kiệm thời gian, giảm lỗi UI và dễ dàng mở rộng. Dưới đây là quy trình thực tế đã áp dụng thành công trong nhiều dự án.
1. Chọn kiến trúc Monorepo
- Sử dụng Nx hoặc Turborepo để quản lý các package: `ui-core`, `ui-web`, `ui-native`.
- `ui-core` chứa token thiết kế (màu, spacing, typography), theme provider và các component logic‑only (Button, Input, Card) viết bằng TypeScript thuần.
2. Tách component theo platform
- Mỗi component trong `ui-core` chỉ định nghĩa props và hành vi chung.
- `ui-web` và `ui-native` sẽ re‑export component và cung cấp implementation riêng: `Button.web.tsx` dùng `<button>` và CSS‑in‑JS, `Button.native.tsx` dùng `<Pressable>` + `react‑native‑styled‑components`.
- Sử dụng `react-native-web` cho các component đơn giản để tái dùng code, nhưng giữ file riêng cho các API native (shadow, haptic feedback).
3. Theme và Dark Mode tập trung
- Định nghĩa `theme.ts` trong `ui-core` với palette, spacing scale, border radius.
- Cung cấp `ThemeProvider` bọc toàn bộ app; cả web và native đều consume cùng một context.
- Dark mode chỉ cần toggle `theme.mode` – không cần sửa component con.
4. Storybook đa nền tảng
- Cấu hình Storybook cho `ui-web` (web) và `ui-native` (React Native) bằng `@storybook/react-native`.
- Viết story một lần trong `ui-core` (`.stories.tsx`) và import vào hai Storybook; story sẽ render implementation phù hợp nhờ alias path.
5. CI/CD kiểm tra visual regression
- GitHub Actions chạy `chromatic` cho web và `storybook‑visual‑test` cho native (sử dụng `detox` + `pixelmatch`).
- Mỗi PR tự động so sánh snapshot; chặn merge khi diff > 0.5% pixel.
6. Phân phối package
- Publish `ui-core`, `ui-web`, `ui-native` lên npm private registry với version cùng nhau (`1.2.0`).
- Ứng dụng web cài `@myorg/ui-web`, mobile cài `@myorg/ui-native`; cả hai đều peer‑depend trên `@myorg/ui-core`.
Lời khuyên áp dụng ngay:
- Bắt đầu từ token thiết kế, không vội xây component phức tạp.
- Viết test unit cho logic component trong `ui-core` (Jest) – chạy chung cho cả hai platform.
- Đặt quy tắc naming: `ComponentName.platform.tsx` để dễ tìm kiếm.
- Review UI định kỳ với designer qua Storybook để phát hiện lệch sớm.
Với cách tiếp cận này, team có thể phát triển feature mới chỉ một lần, đảm bảo brand consistency và giảm ~40% effort UI maintenance.