diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4913bd1..892fd2a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,3 +20,15 @@ docs: trim local setup to the essentials
## Build outputs
`imagediff.js` and `imagediff.min.js` are generated by `npm run build` and committed for releases. Rebuild and commit them only when preparing a release; ordinary PRs change `js/imagediff.js` and leave the built files alone. `npm test` runs against the source, including the CLI, so nothing needs rebuilding to test a change.
+
+## Releasing
+
+In the release PR, run:
+
+```sh
+npm run release
+```
+
+It builds `imagediff.js` and `imagediff.min.js` and runs `npm test` against each, through `require` in Node and in a page. Commit the built files once it passes. It doesn't bump the version, tag or publish.
+
+After merging, `npm publish` checks the committed built files again before publishing: it refuses if they differ from what's committed or if the specs fail against them. It doesn't rebuild, so what's published is what's committed.
diff --git a/README.md b/README.md
index b8eb422..343457e 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,8 @@ npm test
* `npm run test:node` runs the specs, including a smoke test of the `imagediff` CLI, in Node.js against [node-canvas](https://github.com/Automattic/node-canvas) (the optional `canvas` dependency, which `npm ci` installs from prebuilt binaries on common platforms).
* `npm run test:browser` runs the specs in headless Chromium with Playwright.
* `npm run test:serve` serves the specs at http://localhost:8085/spec/ to watch them run in a browser.
+* `IMAGEDIFF_LIBRARY=imagediff.min.js npm test` runs the same specs against a built file (a path from the repository root) instead of the source: through `require` in Node and as a `
-
+