What you can share (most of it)
The valuable, expensive-to-write code is platform-agnostic: TypeScript types, validation schemas, API client, business logic, and domain models. In a monorepo those live in shared packages that both the Next.js app and the React Native app import. You write the rules of your product once, and both platforms obey them.
// monorepo layout
// packages/core -> types, validation (zod), domain logic (shared)
// packages/api -> typed API client (shared)
// apps/web -> Next.js (imports @acme/core, @acme/api)
// apps/mobile -> React Native (imports @acme/core, @acme/api)
// apps/server -> Node/Express BFF (imports @acme/core for shared types)What you must NOT share: the platform edges
UI is platform-specific (React DOM vs React Native primitives) — sharing it is where 'write once, debug everywhere' pain comes from. And some things are dangerously different: token storage. On web, an auth token belongs in an httpOnly cookie; on mobile, it belongs in the secure keychain/keystore. Sharing that code would either weaken web security or break on mobile. Keep the storage adapter platform-specific behind a shared interface.
Share the logic, not the platform edges. Auth-token storage, navigation, and UI primitives differ by platform for good reasons — abstract them behind a shared interface, don't force one implementation.
A Backend-for-Frontend keeps both honest
A thin Node/Express BFF sits between both apps and your services, shaping responses for exactly what the clients need and holding shared server-side types. It means the mobile app isn't making five round-trips where the web app makes one, and both consume one consistent, typed contract.
The realistic share ratio
- High share: types, validation, API client, business/domain logic, formatting.
- Partial share: state management patterns and hooks (often shareable with care).
- No share: UI components, navigation, and secure storage — platform-specific by design.
Key takeaways
- A TypeScript monorepo lets web and mobile share the expensive logic and types.
- Share business logic, validation and the API client; keep UI and storage platform-specific.
- Store tokens in httpOnly cookies on web and the secure keychain on mobile — behind one interface.
- A Node/Express BFF gives both clients one consistent, typed contract.