Home / Insights / Architecture and Modernization
Architecture and Modernization
One Codebase or Several? Sharing Code Across Web and Mobile Without Regret
Sharing code across web, iOS and Android can cut cost and keep behaviour consistent, but sharing the wrong layer creates compromises users notice. This guide compares the options, from fully shared UI to shared logic with native interfaces, and shows how to decide.
TopicsArchitecture and ModernizationMobile App DevelopmentWeb and SaaS Development
Key takeaways
- The real question is not one codebase or several, but which layers to share: UI, business logic, API contracts, design tokens or tests.
- Sharing API contracts, design tokens and validation rules is almost always worthwhile and low risk.
- Shared business logic with native or platform-specific UI — for example with Kotlin Multiplatform or shared TypeScript packages — balances consistency with platform quality.
- Fully shared UI across web and mobile (React Native with web support, Flutter web) works best for internal tools and content-light apps; check web performance and SEO needs carefully.
- A monorepo with clear package boundaries, shared CI and versioned contracts makes any level of sharing easier to manage.
On this page
Most products eventually need a web app and mobile apps. Building each separately doubles or triples the work and lets behaviour drift: a discount rule implemented three times will eventually be implemented three different ways. Sharing everything, on the other hand, can produce a web app that feels like a mobile app, or mobile apps that feel like websites.
This guide focuses on the decision of what to share between web and mobile. For the narrower question of native versus cross-platform mobile frameworks, see our guide to native versus cross-platform development.
What can be shared
| Layer | Examples | Sharing value | Risk |
|---|---|---|---|
| — | — | — | — |
| API contracts | OpenAPI or GraphQL schemas, generated clients and types | High | Low |
| Design tokens | Colours, typography, spacing | High | Low |
| Validation and business rules | Pricing, eligibility, form validation | High | Medium: platform-specific edge cases |
| State and data logic | Caching, sync, offline handling | Medium to high | Medium |
| UI components | Buttons, forms, screens | Varies | High: platform conventions differ |
| Tests | Contract tests, business-rule tests | High | Low |
Share from the top of this table downwards, stopping where the risk exceeds the value.
The main approaches
Separate codebases
Web in a web framework, iOS in Swift, Android in Kotlin. Best platform fit and performance, at the highest cost. Shared API contracts and design tokens still reduce duplication.
Shared business logic, platform-specific UI
Core logic lives in shared packages; each platform builds its own interface. Options include Kotlin Multiplatform, which JetBrains declared stable in November 2023 and which lets teams share logic while keeping native UIs, and shared TypeScript packages used by a React web app and a React Native mobile app.
Shared mobile UI, separate web
One cross-platform framework (Flutter or React Native) for iOS and Android, and a separate web front end — often the most practical choice for consumer products that need a strong web presence and SEO.
Fully shared UI across web and mobile
Flutter with web support, or React Native with React Native Web, serves all platforms from one UI codebase. Efficient for internal tools, dashboards and apps without SEO needs, but web performance, accessibility and browser conventions need careful attention.
Decision matrix
| Factor | Points towards more sharing | Points towards less sharing |
|---|---|---|
| — | — | — |
| Team size and budget | Small team, tight budget | Large teams per platform |
| Product type | Internal tool, B2B workflow app | Consumer product with strong brand and platform polish |
| Web requirements | Logged-in app; no SEO | Public content, SEO and fast first load critical |
| Platform features | Standard UI and APIs | Heavy use of camera, sensors, widgets, wearables, background tasks |
| Consistency | Complex business rules must match exactly | Platforms intentionally differ |
| Existing code | Shared language already in use | Mature native apps already in production |
Score your product; most land on shared logic and contracts with at least partly separate UI.
Making sharing work in practice
- Use a monorepo with clearly separated packages — contracts, tokens, domain logic, web app, mobile apps — so changes to shared code are visible and tested together.
- Generate clients from API contracts so every platform uses the same types.
- Version shared packages and run each app’s tests when shared code changes.
- Keep platform-specific code in clearly marked places rather than conditional statements throughout shared code.
- Align releases: mobile releases go through app-store review while web deploys instantly; feature flags help keep behaviour consistent.
Worked example: a B2B field-service product
A hypothetical company offers a web portal for office staff and mobile apps for field technicians. Business rules — job pricing, SLA calculations, eligibility checks — were implemented separately in the web app and in two native mobile apps, and customers kept finding differences.
The team chose to:
- Generate typed API clients for all three apps from one OpenAPI contract.
- Move pricing and SLA rules into a shared TypeScript package used by the React web app and a new React Native mobile app, replacing the two native apps over two releases.
- Keep offline sync and camera features in platform-specific modules.
- Share design tokens so the apps look related without forcing identical layouts.
Defects caused by rule differences stopped appearing, and new rules now ship to all platforms in one change.
Cost perspective
Separate codebases cost the most to build and maintain, but sharing is not free: shared code needs more careful design, broader testing and coordination between teams. The saving comes mainly from not implementing and fixing business logic multiple times. For most products, sharing contracts, tokens and business logic delivers the majority of the benefit with the least compromise.
Frequently asked questions
Can one codebase really serve web, iOS and Android well?
For some products, yes — especially internal or logged-in apps. Consumer products with public web content usually benefit from a separate, web-optimised front end.
Is React Native or Flutter better for sharing with web?
React Native pairs naturally with a React web app through shared TypeScript logic and, optionally, React Native Web. Flutter can target web directly from the same UI code. The right choice depends on your web requirements and team skills.
What should we share first in an existing product?
Start with API contracts and generated clients, then design tokens, then the business rules that most often diverge between platforms.
Does sharing code slow down releases?
It can if shared packages are poorly versioned. With a monorepo, automated tests and feature flags, it usually speeds up consistent releases.
Sources and methodology
Facts in this article were checked against the sources below on 6 November 2026. Directory data (ratings, review counts, rate bands and team sizes) changes over time and is shown as published on the date accessed. Illustrative examples are labelled as such and are not quotes.
- JetBrains: Kotlin Multiplatform is stable and production-ready (November 2023) — accessed 6 November 2026. Core Kotlin Multiplatform technology stable in Kotlin 1.9.20; teams share logic while keeping native UIs
Related reading
Continue your research
Building for web, iOS and Android?
Share your product and team. We will help you decide what to share, choose frameworks and set up a codebase structure that keeps delivery fast.
