How do you run a shared mobile platform for many apps and teams: layering, ownership, versioning and governance?

15.6.2 · L8 · Interview

Predict first

Two teams want to share a component that looks similar in both apps but changes for different business reasons. What is the best choice?

// A: move it into the platform immediately so there is one copy
// B: keep separate copies until the common core is clear, then share only that
// C: copy it into every app without limits
  • A
  • B
  • C

Mental model. A platform is a shared airport: airlines (apps) bring their own planes and schedules, but runways, security and signage are common, owned and standardised, because every airline needs them to work the same way every day.

A platform serves other engineers as its customers: dozens of teams and several apps share components (design system, networking client, auth, analytics, feature flags, onboarding flows). The design goals pull against each other: reuse (do not rebuild login five times), autonomy (teams ship on their own schedule), consistency (one look, one behaviour) and stability (a shared change must not break twenty apps). Structure it as layers with a dependency rule: foundations (logging, utilities, networking transport, storage), platform services (auth, config and feature flags, analytics, payments, deep-link routing), UI building blocks (design system), and product features that apps compose. Each platform capability is a module with a small, documented, versioned public interface, plus a protocol-based way to supply the app-specific parts (the base URL, brand colours, a token provider, analytics sinks), so the platform contains mechanism and the app injects policy (see the networking client platform and feature module questions). Apps are thin shells that depend on the platform and wire features in a composition root.

Operate it like a product. Ownership: every module has an owning team, a roadmap, an on-call and a contribution process (inner-source: others can send changes, owners review). Versioning and releases: semantic versions, a changelog, a deprecation policy with a published window (see API evolution), and automated checks for source and binary breakage in CI (API diff tools, module stability). Compatibility: support at least the last two versions in the field; roll platform changes out behind flags and to a few apps first; keep the platform’s own tests, sample app and previews healthy, and build every consuming app in CI against platform changes so breakage shows up before release. Governance without bureaucracy: an architecture review for new platform modules and breaking changes, clear criteria for what belongs in the platform (used by two or more apps, stable, owned) versus what stays in an app, and a rule against a “Common” junk drawer. Developer experience: fast builds (modules, caching, binary frameworks for stable layers), templates that generate a feature module with tests, documentation with examples, and metrics (adoption, build times, defects per module). Watch the failure modes: a platform nobody can change (too rigid), one that changes constantly (no one can depend on it), a tight central team that becomes a bottleneck, and premature sharing of code that only looked similar. Share what is actually common, keep the rest per app, and prove the value with measured adoption.

Premature sharing couples teams that change for different reasons. Duplication is cheaper than the wrong abstraction until real commonality emerges.

Platform providesApp provides
Networkingtransport, retries, auth refresh, loggingbase URL, endpoints, token provider
Design systemcomponents, spacing, accessibility behaviourbrand colours and fonts, app-specific layouts
Analyticsevent pipeline, batching, consent handlingevent names and properties for its features
Feature flagsevaluation, caching, kill switcheswhich flags it reads, defaults
Releasesversions, changelog, compatibility checksupgrade schedule, consumer tests

Common traps

  • Moving code into the platform because it looks similar. If it changes for different reasons per app, sharing creates coupling; wait for real commonality.
  • Shipping platform changes without building all consuming apps in CI. Breakage appears in someone else’s release; test consumers continuously.

They might follow up with

  • What does the platform contain versus the app? Mechanism in the platform; policy (URLs, branding, token source) injected by the app.
  • How do you avoid a bottleneck? Inner-source contribution with clear ownership, review and templates.

Related questions

  • 15.3.1 What is a feature module, how do you draw module boundaries, and how does access control enforce them?
  • 15.5.2 How do you evolve a public API without breaking callers: deprecation, renames, versioning and source versus…
  • 12.6.2 How would you design a networking layer shared by many apps and teams: interceptors, mocking, and URLProtocol?

← How do you apply the SOLID principles in Swift without…