StatsHub Docs

Packages

The native kit, the shared catalogs and the product config — three workspace packages, 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-configFeature flags and product metadata, the same file web reads
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.

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