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.
| Package | What this app takes from it |
|---|---|
@statshub/ui-native | Every shared primitive, built for React Native |
statshub-api-client | URL building, JSON transport, cancellation, and typed HTTP errors shared with web |
statshub-config | Feature flags and product metadata, the same file web reads |
statshub-i18n | The 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.