StatsHub Docs

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. A file under src/app/(main)/, in the group it belongs to — (tabs), (detail), (tools), (filters), (settings).
  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. How the screen is presented — push, modal, sheet — is a route-table decision, not something the screen sets. See Architecture.
  4. States. Loading, empty and failed are decided once and applied; see Errors.

Add a filter sheet

Filters are routes here, under (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/, and keep the state in the store the board reads. Zustand owns it, not the URL: there is no URL to put it in.

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