async-safety
Async safety
No async failure in an Expo app is silent and no async result lands where it no longer belongs: every
promise has an owner that sees its rejection, every effect cancels the work it started, overlapping
calls resolve latest-wins, cancellation is read from the signal (with only the abort APIs a phone
really has), every subscription and timer is released by whoever created it, and every wait has a
deadline. A zero-dependency checker proves the parts ESLint and tsc cannot see, on iOS and Android
code alike; race tests prove the rest.
Rules that must hold
The inline handler forms (no floating promise, no async handler, block-bodied handlers) are
typescript-and-lint-rules rule 10 and its ESLint config; these rules close everything after them.
Server data is read with useQuery (networking-and-server-state): no effect, no
createLatestRequest, because query keys already give latest-wins and TanStack passes the signal.
Rules 3 and 4 are for async work that is not server state: SQLite repositories, native SDKs, OS
reads, device APIs.