StatsHub Docs
General

Packages

The native kit and the shared catalogs — the workspace packages this app takes, and the reason the native app cannot use the web one.

PackageWhat this app takes from it
@statshub/ui-nativeEvery shared primitive, built for React Native
statshub-api-clientURL building, JSON transport, cancellation, and typed HTTP errors shared with web
statshub-i18nThe en / es / pt catalogs and the formatting helpers

Two UI kits, not one

@statshub/ui-web is not importable here and never will be. A <div> does not exist in React Native, Tailwind class strings are resolved by a different engine, and the platform's own controls have no web equivalent — a shared kit would be a lowest common denominator neither app wants.

What the two kits do share is the vocabulary: a component with the same job has the same name, the same variant names and the same prop shapes in both. So a change on one side has an obvious counterpart on the other even though no code crosses.

@statshub/ui-native also ships things the web kit has no reason to — glass effects, haptics wiring, sheet presentation — because those are the platform, not the design system.

The catalogs are genuinely shared

statshub-i18n is platform-neutral on purpose: it imports no UI framework, and statshub-i18n/react holds the hook both apps use. A string translated for the website is translated for the app, which is the whole reason the package exists rather than two copies of the same JSON.

The feature catalogue is not a package

src/lib/config/ holds what tools exist, what they are called, which group they list under and which of them this platform carries. It was statshub-config and both apps imported it; now apps/web-app-router/src/lib/config/ is a second copy of the same catalogue. Add a tool to one and it does not appear in the other — that is the cost of the split, and the header of each index.ts says so.

Where a component belongs

  • src/components/features/<area>/ — parts one screen or one board uses.
  • src/composed/ — assembled pieces two screens share.
  • @statshub/ui-native — a primitive with no StatsHub domain knowledge in it. If it mentions a fixture, a prop or a hit rate, it is not a primitive.

Not a package: the backends

Convex lives in convex/ inside this app rather than in packages/. It is this app's account store — the profile table and Better Auth — and nothing else reads it. Match data comes from the API like everywhere else; see Data.

On this page