How Multica Shares a Single Codebase Across Web, Desktop, and Mobile

The article explains Multica's three‑layer contract architecture—core, ui, and views—and how enforcing a downward‑only dependency flow lets web, Electron desktop, and React Native mobile apps share a single codebase while avoiding duplication, version drift, and runtime mismatches.

Hacker Afternoon Tea
Hacker Afternoon Tea
Hacker Afternoon Tea
How Multica Shares a Single Codebase Across Web, Desktop, and Mobile

Multica’s eighth “拆解” article explains how a single codebase can serve web, desktop (Electron), and mobile (React Native) by structuring the repository into three contract layers.

Three contract packages

@multica/core

– data contract layer: type definitions, API client, WebSocket client, React Query logic; no UI, peerDependencies only React. @multica/ui – DOM primitive layer: shadcn‑style components like Button, Dialog, Sheet; depends on react‑dom. @multica/views – feature view layer: assembled business screens that depend on both core and ui.

Dependency direction

Dependencies flow only downward. Web and desktop apps depend on all three packages, while the mobile app depends solely on @multica/core, avoiding UI and view packages that require DOM.

Core contract details

Core’s package.json declares only react as a peer, allowing it to run in Next.js server components, Electron renderer, or React Native. It exports a nested cache‑key factory ( issueKeys) that distinguishes prefix for invalidation and full key for query options, establishing a product‑wide caching contract.

export const issueKeys = {
  all: (wsId) => ["issues", wsId] as const,
  /** PREFIX for invalidation — no sort. */
  list: (wsId) => [...issueKeys.all(wsId), "list"] as const,
  /** FULL KEY for queryOptions — includes sort. */
  listSorted: (wsId, sort) => [...issueKeys.list(wsId), sort ?? {}] as const,
  /** All "my issues" queries — use for bulk invalidation. */
  myAll: (wsId) => [...issueKeys.all(wsId), "my"] as const,
  detail: (wsId, id) => [...issueKeys.all(wsId), "detail", id] as const,
};

Invalidating with invalidateQueries({ queryKey: issueKeys.list(wsId) }) clears all related caches, while queries use the full key.

UI vs. Views

UI packages contain only DOM components with react-dom as a peer. Views import UI primitives and core types, then compose them into screens, e.g., issue-detail.tsx imports UI components and core types/mutations.

Mobile‑only core usage

The mobile app’s package.json lists only @multica/core plus native primitives ( @rn-primitives/*, nativewind). It re‑implements its own query logic because React Native’s networking and caching differ from the browser.

// apps/mobile/app/(app)/[workspace]/issue/[id].tsx
import type { Issue } from "@multica/core/types";
// only type import, no runtime logic

Mobile also defines its own queries, e.g., using @/data/queries/workspaces with useQuery from React Query.

Version consistency

All packages share the same React, React‑DOM, Zustand, React Query, and Zod versions via pnpm’s catalog: mechanism defined in pnpm-workspace.yaml, preventing version drift.

# pnpm-workspace.yaml
catalog:
  react: "19.2.3"
  react-dom: "19.2.3"
  zustand: "^5.0.0"
  "@tanstack/react-query": "^5.96.2"
  zod: "^4.1.5"

Result

This three‑layer contract, enforced with exports and strict dependency direction, lets two developers maintain ten agents without code chaos. Changes in core propagate safely to all three platforms, turning “change once, sync everywhere” into a verifiable fact.

Architecture diagram
Architecture diagram
Architecture diagram
Architecture diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

FrontendReactMonoreporeact-nativecode sharingMultica
Hacker Afternoon Tea
Written by

Hacker Afternoon Tea

You might find something interesting here ^_^

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.