AGENTS.md
Guidance for AI coding agents in this repo. Human contributors: see the Contribute section of the README.
This is react-fetch-streams: React hooks for streaming a response body over the Fetch + Streams
APIs (useStream, plus useNdjsonStream for newline-delimited JSON) and for Server-Sent Events
(useEventSource, useEventStream). It is a small,
dependency-free, published npm library written in TypeScript. Keep it that way; think twice before
adding a runtime dependency.
The toolchain is the Rust-based oxc stack: oxlint to lint,
Prettier to format, tsdown (Rolldown + oxc) to
build and emit declarations, and Vitest to test; TypeScript (tsc --noEmit)
type-checks. There is no Babel, ESLint, or Rollup; do not reintroduce them.
Workflow
- Clarify the design before implementing. For anything non-trivial, agree on the approach first.
- One unit of change per commit. Never mix unrelated changes. Present the change for review before committing.
- Every change ships with tests. Run local CI before calling it done, and do not claim it passes without running it.
- Verify against the code and the tools: read before you answer, run before you assert.
Local CI (must be green before review):
npm run typecheck # tsc --noEmit
npm run lint # oxlint
npm run format:check # prettier
npm run build # tsdown
npm run test:cov # vitest
Writing: code, comments, docs, commits
- Concise and to the point. No fluff. Explain the non-obvious; do not narrate the obvious.
- ASCII only. No em-dash and no
--; write-. Use->not the arrow glyph,!=not the not-equal glyph, and so on. - Comments justify why, not what. Delete any comment that restates the code.
- Formatting is not a matter of taste: Prettier owns it. Run
npm run formatrather than hand-formatting. House style (.prettierrc.json) is single quotes, no trailing commas, no bracket spacing, and arrow parens omitted when possible.
Commits
- Conventional Commits. Write the subject in the present
tense, imperative voice:
feat: add retry option, notaddedoradds. - Keep the body minimal, or omit it. A good subject plus the diff is usually enough; add a body only for what the code cannot show (why, a trade-off, a non-obvious consequence). Never restate the change or narrate the diff.
- Disclose AI with an
Assisted-by: Claude:claude-opus-4-8trailer. NeverCo-Authored-By, and never add a human’sSigned-off-by.
Tests
- Tests live beside the source as
src/*.test.tsand run under Vitest with the jsdom environment. - Exercise the hook with
renderHookfrom@testing-library/react. Mockfetchdirectly withvi.fn/vi.stubGlobal; do not reach for a mocking library. - The suite drives real async streaming, so keep timing assertions tolerant. Prefer awaiting an observable effect (a callback firing) over sleeping for a fixed wall-clock duration where you can.
- Coverage must not drop. New code ships with tests that hold or raise it. Measure with
npm run test:cov.
Code conventions
- Source is TypeScript (ESM). No JSX in
src- the hooks are UI-agnostic. - Follow the rules of hooks; oxlint’s
reactplugin enforces them. Keep effect dependency arrays honest. - The published API is exactly what
src/index.tsre-exports. Types live in the source and the.d.tsis generated by the build, so there is no separate declaration file to sync; do keep the README usage examples in step with any public change.
Browser support
- The support matrix is the
browserslistfield inpackage.json; it also documents the intent behind the buildtargetintsdown.config.mjs. Keep the two consistent. - Do not silently narrow or widen support. Changing it is a deliberate change: update the README “Browser Support” section to match.
Build and publish
npm run buildbundlessrcwith tsdown intodist/(CommonJS, ESM, minified UMD, and the generated.d.ts/.d.mts). What ships to npm is thefilesallowlist inpackage.json; keep it accurate.- Do not hand-edit anything in
dist/- it is generated.
CI workflows
- GitHub Actions live in
.github/workflows. Write the workflowname:, every job name, and every named step in Sentence case. - Keep workflows minimal and scoped to one purpose; prefer the built-in
GITHUB_TOKENover a personal access token.