May 21, 2026/1 min read/Boilerplate Team
One product surface, two clients
How the web and native apps share a typed backend without forcing the same UI decisions.
ExpotRPCMonorepo
A web app and a native app should share product behavior, not every component.
This stack keeps the API, auth, database, and environment contracts in shared packages. The web and Expo apps consume those contracts through tRPC and their own client setup.
Shared where it matters
The shared layer is intentionally practical:
- API routers define the product operations.
- Auth configuration stays in one package.
- Database schema and queries stay close to Drizzle.
- Environment validation catches missing runtime configuration early.
That gives both clients a common foundation without forcing mobile navigation, layout, or styling into web-shaped patterns.
Separate where users feel it
Native screens should feel native. Web routes should feel like web routes. The monorepo is there to reduce duplicate product logic, not to flatten platform differences.
Good shared code removes friction. Bad shared code exports friction.