CodeVetter · Repo Unpack · Risk map
pmndrs/jotai
These are source observations and explicitly identified hypotheses, not confirmed vulnerabilities. The core's main correctness risks involve dependency/lifecycle ordering, deep reads, and pending promise retention. External trust boundaries appear in storage, example network content, and website contact handling. Several documentation and dependency mismatches require care when using ancillary applications to validate the root library.
- AtomState.p strongly retains pending dependents; the source explicitly notes possible memory leaks, and removal occurs when the associated promise settles. Hypothesis: never-settling promises can prolong retention beyond the ordinary weak-map lifecycle. (inferred)
- Graph reads and mounting recurse even though invalidation/recomputation use iterative traversal; a regression explicitly expects sufficiently deep reads/subscriptions to overflow. Reads that mutate the store receive a development warning rather than enforced rejection.
- Storage JSON parsing accepts any valid JSON shape. withStorageValidator wraps getItem but copies subscribe unchanged, and atomWithStorage updates memory before persistence; validation of external subscription values and rollback after storage failures are not implemented in these functions.
- Both contact handlers check only truthiness of name/email/message before sending email; their bodies contain no method restriction, authentication, rate-limit, size, or email-format checks. The form's honeypot is client-only and is not included in its POST body; deployment-level controls were not verified.
- Support.handleSubmit sets hasSubmitted before fetch, has no catch/reset branch, and handles only status 200. Its overlay displays Sending... whenever submission started but hasReceived remains false, including the visible non-200 path.
- The Hacker News example casts response.json() to PostData without runtime validation or response.ok handling, passes external text to html-react-parser, and uses external url values directly in links. These are content-validation boundaries; exploitability was not tested.
- The root is v3.0.1, but the website declares jotai ^2.4.1 and the atomFamily example ^2.10.4; that example imports atomFamily from jotai/utils even though v3 documentation moves it to jotai-family. These surfaces do not directly validate the root v3 implementation.
- The useAtomValueRaw documentation says render-to-subscription changes are missed, whereas createState now rereads immediately after store.sub and invokes the callback when changed. Separately, website SSR theme bootstrap catches storage reads but leaves JSON.parse and its initialization write outside that catch.