Benchvale

How we build tools

Every tool on this site does its work inside your browser. Nothing you type is sent anywhere, and that is not a promise you have to take on faith: there is a test that fails the build if any tool page makes a network request it should not, and you can check the claim yourself in about ten seconds.

Check it yourself, in ten seconds

Open any tool on this site. Let it load, then turn off your wifi and use the tool. It keeps working.

Loading the page in the first place does need a connection. These tools run inside the page rather than being installed, so the promise is that nothing leaves your browser once you are there, not that the site is available with no network at all.

If you want to be stricter about it, open your browser's developer tools, go to the Network tab, and use the tool with the recording on. You will see the page and its assets load, and then nothing. No request goes out when you type, when you change an option, or when you copy a result.

That is the whole claim, and it is deliberately the kind of claim you can disprove. A privacy policy is a document. This is a behavior you can observe.

Two pages that make the check specific: is it safe to paste JSON into an online formatter and is it safe to use an online password generator. Once either tool page has loaded, the network tab should stay quiet when you paste or generate. The JSON formatter and the password generator are the tools those articles send you to.

The test that keeps it true

Claims decay. Someone adds a font from a CDN, or an analytics snippet, or a share button that phones home, and eighteen months later the sentence on the page is a lie that nobody meant to tell. So the claim is enforced by the build rather than by memory.

Every time this site is built, an automated check loads each page in a real browser, types a distinctive marker string into every input, clicks every button, and then inspects the network requests that session recorded on the document timeline. The build fails if:

On each tool page, the control strip's REQUESTS patch counts cross-origin entries from the browser's Resource Timing API on the document timeline. That live count does not include requests made inside a web worker, the final host after a redirect when only the initial URL is recorded, or preconnect hints (Resource Timing does not expose them). Worker and redirect coverage is tracked on the board as follow-up work; the measured catch ratio on those shapes was three of six when last audited.

That last one is worth explaining, because it is the mistake this design nearly made.

Why share links use the part after the #

Several tools here let you share a configured link. When you copy a share link from the contrast grid, the palette travels in the URL. It looks like this:

benchvale.com/design/contrast-grid#p=131A22-1E5470-2FBFD0

Note the #. Everything after it is called a fragment, and browsers never transmit it to a server. It exists only on your machine and on the machine of whoever you send it to.

The obvious way to build that feature is a query string, with a ? instead of a #. Every framework nudges you toward it and it works exactly the same from the user's side. It is also wrong here, because a query string is sent to the server with every single request. The moment anyone opened a shared link, the palette would have arrived in a server log, and this page's central claim would have been falsified by our own share button.

We caught that in review before anything shipped, and the build now refuses any navigation carrying a query string on a tool page. It is a small technical detail that decides whether the promise is real.

What we do load

A page here loads its own HTML, one small stylesheet, one font file, and for tool pages a small script. All of it is served from this domain. There is no CDN, no tag manager, no embedded widget, and no third-party font. Nothing is loaded from a server that is not ours or on the published allowlist, which means no other company learns that you visited unless we have named that host in advance.

The scripts are small on purpose. Every tool page ships under 100 KB of transferred JavaScript except the password strength checker, which may use up to 250 KB so it can score against a real leaked-password dictionary rather than a regex. The build fails on any page that exceeds its stated budget. The contrast grid stays small because a contrast ratio is six lines of arithmetic and does not need a framework; the budget gate compresses each served resource separately at the level measured on our host, matching what the Network panel exposes.

Where the math comes from

Anything that calculates says what it is calculating and where the rule comes from. We do not want you to trust the number, we want you to be able to check it.

Contrast ratios use the WCAG 2.2 definition, which is unchanged from 2.1 and 2.0. Each color's relative luminance is computed from its sRGB channels, each channel is linearized, and the three are weighted 0.2126 red, 0.7152 green, 0.0722 blue. The ratio between two colors is (lighter + 0.05) / (darker + 0.05). The thresholds are 4.5:1 for normal text and 3:1 for large text and interface graphics at AA, and 7:1 and 4.5:1 at AAA.

Where a tool has to make a judgment call rather than a calculation, it says so on the page rather than presenting a choice as a fact.

What the tools will not do

Some things are out of scope here even when a browser can do them. Optical character recognition on a scanned document can run in this tab, but a capable engine is a large download, and none of these tools has taken that into the JavaScript budget. A model too large to download still needs a server. We have not built any of those yet.

When we do, that tool will say plainly what leaves your device and where it goes, and the standing promise will not appear on its page. What will not happen is the promise quietly staying put while the behavior changes underneath it. A claim that is true on most pages is not a claim, it is a trap.

Accessibility

The first tool on this site checks WCAG contrast, so the site itself had better pass. Every build runs an automated accessibility audit against WCAG 2.2 A and AA, and fails on a violation. Every tool works from the keyboard, every input has a real label, and results are announced to screen readers when they change.

Automated auditing catches contrast, labels and roles. It does not catch whether the focus order makes sense or whether an interaction is actually usable without a mouse, so those are checked by hand. If something here does not work for you, please tell us. It goes in the changelog.

Errors

Tools have bugs. When one here produces a wrong answer, the fix and the date go in the changelog with a note about what was wrong, rather than being corrected silently. A tool that visibly gets fixed is a tool that is maintained.

We also correct ourselves in public where it matters. The contrast grid page describes a real failure in this site's own brand palette, with the real number, because it is the exact mistake the tool exists to catch and pretending we had never made it would make the page less useful.

How this site makes money

Advertising, eventually. There are no ads on the site today. When there are, they will sit below the tool and never above it, they will have a fixed reserved space so the page does not jump, and there will be none at all in the classroom projection modes.

Ads do not change the privacy claim about your input, because the tool still runs in your browser and your text still never leaves it. They do mean an advertising network will see that you loaded the page, which is a different thing, and the privacy page says so directly rather than burying it.

Last updated . Only changed when something material changed, which is why some of these dates are old.