StatsHub Docs
General

Guides

Adding a screen, adding a filter sheet, running on a real device, and the export that catches what tsc cannot.

Run it on a device

There is no simulator on the dev box and no way to see a screen from it. Metro runs here; the app runs on your phone.

bun run dev:expo      # Metro on 8142
bun run phone         # a QR code for the dev client

Metro is handed the live Tailscale Serve URL as EXPO_PACKAGER_PROXY_URL, so the dev client connects through tailnet-only HTTPS with a valid certificate. The raw tailnet hostname is retained as a fallback. Nothing to pass.

A native change cannot be verified from the dev box

Typecheck it, say what you built and what remains unchecked, and leave the looking to a real device. Do not imply you saw it.

Add a screen

  1. Route. Add a file at its real URL under src/app. Put a tab-owned screen under src/app/(tabs)/fixtures, player-trends, or prop-screener; put a shared destination such as /player or /profile at the root.
  2. Data. A defineQuery in src/lib/api/<area>/. One declaration gives you the hook, the imperative fetch, the prefetch and the invalidation, all agreeing on the key. See Data.
  3. Presentation. Register exceptional modal or sheet options in the nearest _layout.tsx; ordinary pushes need no presentation entry. See Architecture.
  4. States. Loading, empty and failed are decided once and applied; see Errors.

Add a filter sheet

Filters are routes under filter-sheets/<feature>, filters/<feature>, or a feature-specific stack such as screener-filters. That is what makes a panel linkable, restorable, and dismissible by the back gesture — a modal that is not a route is none of those.

Put the screen beside its siblings in screener-filters/ or player-filters/. A reproducible filter set belongs in Expo Router params; the filter route reads and writes the same board-owned state. Zustand is for saved defaults and durable preferences, not the active shareable selection.

Before you push

bun run typecheck
bunx expo export --platform ios

The export is the one that matters. It catches native resolution failures — a module that resolves in Metro and not in a build — that tsc cannot see, and it is cheaper than finding them in EAS.

Submitting

App Store covers submission and review, and the app-store-review skill audits a build against the guidelines that actually get apps rejected.

On this page