NoWaterProgramming

Editorial

NoWaterProgramming Team

We write about the parts of frontend work the documentation does not cover: what a thing costs, where it breaks, and what we measured when we built it ourselves. The name is the standard - no filler, no padding, no water.

Editorial standards

What earns a page here

The official docs are free, thorough, and rank above us. So an article only justifies existing if it knows something the docs do not.

  • A real build, with the parts that went wrong left in.
  • A real measurement, taken by us, with the method stated.
  • A trade-off named. Every article has to admit at least one genuine cost, limitation or open uncertainty. An article describing a win with no downside is either incomplete or it is an advertisement.

How sourcing works

Every number, statistic, benchmark and quote is traced to a real source or it does not ship. There is no "widely reported" here.

  • We cite upward, to the organisation that did the thing: Chrome behaviour to Google’s own documentation, Firefox behaviour to Mozilla release notes, a research finding to the published paper. Never to a blog post summarising a public source.
  • We never cite our own properties as evidence for a fact. A page we control is not independent confirmation of anything.
  • Sources are published to the reader, each one naming the specific claim it supports.
  • No source and no written exemption means the claim is cut, not hedged.

Images are never generated

Every diagram, screenshot and poster on this site is produced deterministically - typography set in our own type, diagrams drawn from the data, or a real screenshot of the thing being described. Nothing here is an AI image. Readers judge images before text, and one generated picture is enough to make a reader assume the words were generated too.

Cadence, and what happens to bad articles

At most one new article a week, and one improvement pass over an existing article for every new one. We do not publish to a quota, because frequency is not a quality signal.

  • Every article is periodically re-tested against one question: strip the wording out, and would the underlying research still make this meaningfully better than what already ranks?
  • When the answer is no, the article is retired or merged into a better one. That is an expected outcome, not a failure.

Corrections

If something here is wrong, it gets fixed and the change is visible. We do not quietly edit a claim out and leave the page looking as though it always said the right thing. Disclosures are never removed either - when one stops applying it becomes a dated historical note.

What we own

Articles on this site link to these. They are ours, and every article that names one says so in that article.

  • TheTab

    A tab manager browser extension. We build it.

  • Pixel Perfect Advanced

    A design-overlay browser extension. We build it, and the article about how it works is written from the inside.

Articles(19)

We ran the React Compiler rules in eslint-plugin-react-hooks 7.1.1 over six public React codebases and read a random sample of what they flagged. Over a thousand new errors, three real bugs in 53 sites, and a third of the refs errors never touch a ref. Here is which rules to fix, which to fix mechanically, and which one to keep strict.

React20 min readBy NoWaterProgramming Team

Flipping cacheComponents on turns silent build-time data freezes into build errors. We put 29 code patterns through 110 builds on Next.js 16.1.7 and 16.3.5, one pattern per build, and recorded every error verbatim. Twelve patterns fail. Two stop compiling. The pass/fail is identical across both versions - the amount of help you get is not.

Next.js28 min readBy NoWaterProgramming Team

Tailwind v4 stopped reading tailwind.config.js automatically, and the @config directive brings it back. We probed all 19 keys of a real v3 config against Tailwind 4.3.3, one key per build, and diffed the output CSS. Most keys work. Four are dropped in silence. And the documented list of what does not work is wrong about safelist.

CSS15 min readBy NoWaterProgramming Team

We measured client-side navigation on a deployed Next.js 16.1 site: a soft navigation transfers about half the bytes of a full page load, and a <Link> prefetch transfers the same payload as the navigation it prepares - the whole route, once per link in the viewport, in production. Then we read the useRouter return type out of the installed package: six methods, and no router.events, router.query, router.pathname, router.isReady, router.beforePopState or shallow routing.

Next.jsReact19 min readBy NoWaterProgramming Team

We seeded thirteen failure modes into Next.js 16.1 route handlers and recorded the status, headers and body the client got back, under next dev and under a production build. An uncaught throw is an empty 500 with no Content-Type. Throwing a Response does not set its status. A stream that fails after its first byte is a truncated 200. Dev and production returned the same thing every time.

Next.js15 min readBy NoWaterProgramming Team

We ran npx @tailwindcss/upgrade on a production Astro site, moving Tailwind 3.4.19 to 4.3.3. The tool rewrote the PostCSS config, translated and deleted tailwind.config.mjs, and renamed classes across 31 files, all correctly. It also left two build-breaking errors specific to Astro, and the main stylesheet came out 28% larger gzipped.

CSS13 min readBy NoWaterProgramming Team

A walkthrough of QR internals against the spec: the module grid and its reserved regions, encoding modes, Reed-Solomon over GF(256), interleaved blocks, mask selection, and what the standard deliberately does not protect.

File Formats9 min readBy NoWaterProgramming Team