WhyTho

Every element on a page is a decision somebody made, and almost none of those decisions are written down anywhere. WhyTho pins the reasoning to the element itself.

What It Is

WhyTho is an annotator for webpages. You start it on a page with a browser extension, a bookmarklet, or a script tag on your own staging site, select an element, and write down why that element is the way it is. A numbered pin sticks to the element, and the note is stored against a selector rather than against a screenshot or a line number.

Each note carries more than its text. It records the selector, the tag, the element's own words and the text either side of it, the nearest heading above it, the width it was written at, the widths it claims to be about, a category, a status, and its author. Run it through the extension and it also keeps a screenshot of the element, cropped with enough of the page around it to place it, with the element outlined.

The point is that six months later the note can be understood without opening the page, and still means something after the page has changed. Attribution comes from the account rather than a name field, so nobody types their own name and nobody can claim to be someone else.

Selection works the same on both ends: click on desktop, press and hold on a phone. The note editor opens anchored to the element it describes, so your eye never leaves the thing you are writing about. The whole interface lives in a shadow root, so the page being annotated cannot restyle it and it cannot leak styles into the page.

The Problem It Solves

A site accumulates decisions faster than anyone documents them:

  • An H1 phrased as a service plus a city, because that is where the demand sits.
  • A canonical pointing somewhere non obvious.
  • A block of copy that reads awkwardly because it answers the question people actually search.

Six months later the reasoning is gone, and what remains is an element that looks arbitrary to whoever inherits it. So it gets changed. Not maliciously, just in the course of a redesign, a CMS migration, or a new writer tidying the copy. The work that produced the ranking is undone by someone who had no way of knowing it was load bearing, and nobody notices until the traffic moves.

Documentation in a separate file does not fix this, because the person about to change the element is looking at the element, not at the file. WhyTho puts the reasoning where the decision is visible.

Where It Gets Used

Four situations, all of them handover in one form or another.

  • Before a redesign. Walk the templates and mark what must survive it. The do not change status exists for exactly this, and it reads as an instruction rather than a preference.
  • Handing a site to a new team. An export of the notes for the pages that matter tells a new developer what is deliberate, which is the thing a repository cannot tell them.
  • Recording an audit where it landed. A finding in a document is an argument. The same finding pinned to the element it changed is a record.
  • Explaining a decision to a client on their own page. Pointing at the element beats describing it, especially when the disagreement is about wording.

How It Works

Four steps, and one constraint that shapes all of them. The loop below plays one note on one page, from selection to what survives a redesign, then starts again.

The note is stored against a selector, with the element's own words and the text around it, not against a screenshot or a line number. It still means something after the page has changed.

  1. Start It On The Page

    The browser extension puts it a click or a keyboard shortcut away. A bookmarklet covers Safari and phones, and a script tag suits a staging site your team lives in. It runs inside the page rather than framing it, because almost every site refuses to be framed.

  2. Select The Element

    Click on desktop, press and hold on touch. The generated selector prefers meaning over position: an id first, then test hooks such as data-testid, then a stable class path, and only then nth-of-type.

  3. Write The Reasoning

    A category, a status, and which widths the note applies to. Tag a person or a team with an @ and it lands in their inbox. Your name is attached from your account, not typed.

  4. It Saves As You Write It

    Notes write through to a database keyed to your account and visible to your organization, with the screenshot and the surrounding text attached. If the network drops they are kept locally and pushed on the next run, and the toolbar says which of those happened.

Three engineering notes worth stating: hashed build classes, from emotion, styled components and similar, are filtered out of generated selectors, because a selector built on them breaks at the next deploy. Notes are matched back to elements on load, and a note whose element has moved is shown as unresolved rather than silently reattached to the wrong thing, since a wrong pin is worse than a missing one. And because the annotator runs on someone else's origin, it cannot hold a normal session, so it carries a per account token and every write is pinned server side to the account that token belongs to.

What It Looks Like

Three of the surfaces, drawn from the live interface.

1Same day plumbing repair in Waltham
2Book a visit today
H1main > section.hero > h1
Service plus city stays, the phrase carries the local demand. @Engineering keep it out of an image.
Applies to
All widthsMobileDesktop
Jake LabateSave
Notes on this page
1 · SEO · decided · JakePrice in the heading, not an image.All widths
2 · Technical · question · FaisalTap target under 44px here.Mobile only
WhyThoSelect4 This widthAll
The annotator on a live page: the editor anchored to the element it describes, the page list on the right, and a toolbar that keeps its shape whatever you press.
WhyThoNotesInboxWorkspaceSetupAPI
www.jakelabate.com4 URLs · 10 notes 2 unread
/products/3 URLs · 9 notes
/products/whytho/1 URL · 3 notes
jimmiesplace.com1 URL · 5 notes
Notes grouped by site and URL, with counts and unread mentions carried up to every level.
WhyThoNotesInboxWorkspaceSetupAPI
Faisal khan tagged youIs this heading the shipped copy?main > h1
Faisal khan tagged SEOPlease confirm the canonical here.link[rel=canonical]
The inbox. Tagging a team reaches everyone on it, and joining a team later brings its history with you.

Who It Is For

Anyone who has to explain a page to someone who will edit it later. Developers inheriting a codebase, SEO consultants handing work back to an in house team, content teams who keep being asked why a heading is phrased that way.

It is most useful on the pages that get touched by people who did not build them, which is to say the templates.

  • Not a comment system. You can tag somebody, but there is no threading and no review workflow. A note is a record, not a conversation.
  • Teams label, they do not restrict. Everything inside an organization is visible to everyone in it. Team names identify who wrote a note and can be tagged in one, but they do not hide anything from anybody.
  • Not a way to annotate a site you cannot open. It runs inside the page, so you need to be able to load the page yourself. The API can create a note for any URL, but nothing verifies that the element was ever there.

Working With Other People

An organization holds teams, and a team holds people. A note written inside an organization is visible to everyone in it, attributed to whoever wrote it and to their team. Notes written outside one stay private to the account that made them, and you can switch between the two at any time.

Type an @ in a note to tag a person or a team:

  • Tag a person and the note lands in their inbox.
  • Tag a team and it lands in the inbox of everyone on it, marked with the team it came through, so nobody mistakes a broadcast for a personal request.
  • Join a team later and you inherit what that team was already tagged in, which is the difference between a new hire starting with context and starting with nothing.

Matching happens in the database rather than the browser, so a note typed by hand, imported from a file, or written through any other route behaves identically. Only the author can edit or delete their own note. Organization admins can remove a page. People join by invite code.

Across Viewports

The same element is often two different decisions at two different widths. A nav that collapses deliberately at 640px, a heading that is allowed to wrap on a phone but not on a laptop. So a note declares which widths it is about, separately from the width it happened to be taken at.

Nothing about another width is hidden from you, it is just marked differently:

  • Notes about other widths draw as outlines rather than disappearing, so you can tell the difference between no note and a note that is not about where you are standing.
  • Notes whose element does not exist here, a burger menu viewed on a desktop, collect in a tray with a count instead of vanishing.
  • One click reopens the page in a real window at the width the note was taken at, with the annotator already running, so the media queries fire honestly rather than being faked with a transform.

In the app, a page can be read as a list or as one column per breakpoint. An empty column says nobody has looked at that width yet, which is the sort of gap an audit is supposed to surface.

The API

Everything the app can do, a script can do. The endpoints live at whytho-api.jakelabate.com and are documented in the API reference. It sits behind a Cloudflare worker rather than being exposed directly, which buys a base url worth printing in documentation and rate limiting enforced at the edge, before a request reaches the database.

24

Endpoints

120

Requests per minute, per key

20

Per minute, unkeyed

Keys are scoped to one workspace and stored as hashes, and each one is created either read only or read and write. A read only key is refused on anything that is not a read, which makes it safe to hand to a dashboard or a build.

What a key can reach, and what it cannot:

  • Reading covers the pages, the notes and what a key can see, with filters for site, path, category, status, author, team, applied width, free text and date.
  • Writing covers notes, pages, teams, membership, invites and the notification inbox.
  • Every write is pinned to the key's owner and workspace, so a key can never reach a row its owner could not reach by hand: only the author edits or deletes a note, only admins change the shape of an organization, and the owner cannot be removed by a key at all.

The use that justifies the whole product is still the first one: a build asks for every note marked do not change and fails when one of those selectors no longer matches anything on the page. At that point the reasoning stops being documentation and starts being a guardrail.

Writing adds the other half of the loop:

  • A deploy can flip a note from proposed to decided once the fix ships.
  • A migration can pour years of audit findings into the right elements.
  • Onboarding a team can be a script rather than an afternoon.

Written by the annotator

Captured

Against a real element, at a real width.

Written through the API

Asserted

Nothing verified it.

One deliberate asymmetry, and each note records which it was, so you can filter on it. A guardrail is only worth having if you can tell what its evidence is made of.

Using It From Claude

WhyTho is a connector. Add the url once and an assistant can search what a page has already recorded, read the open questions, and, if you allow it, write notes back. Anybody with a WhyTho account connects with their own account, so there is no key to copy and nothing shared between people.

It is an OAuth server rather than a shared secret:

  • Claude registers itself and sends you to a consent screen on the WhyTho domain.
  • You choose read only or read and write before approving.
  • Connections are listed in the app with what they can do and when they were last used, and revoking one takes effect on the next request.
  • Write access is not implied. The tools that create, edit and delete are hidden entirely from a read only connection rather than failing when called.

The useful part is not asking an assistant to write notes, it is asking it to read them:

  • What did we decide about this template?
  • Which elements are marked do not change?
  • What has nobody answered yet?

That is a different question from what a codebase can answer.

Status And Access

It is live, anyone can sign up, and the annotator itself is free.

Status and access

Status
Live
Address
whytho.jakelabate.com
Sign-in
GitHub, Google, or an email address with a password or a one time link.
How you start it
A browser extension for Chrome, Edge, Brave and Arc, installed from a downloaded package rather than a store. A bookmarklet everywhere else, including Safari and phones. A script tag for a staging site you control.
Sharing
By organization. Everyone invited sees every note written in it. Outside an organization, notes are private to the account.
Cost
Free
API
Read, or read and write, at whytho-api.jakelabate.com, with per workspace keys you create and revoke yourself. A write key can do anything you can do in the app.
Claude connector
Add whytho-api.jakelabate.com/mcp as a custom connector and sign in with your own account.
Stored data
Your notes and the URLs they were written on, behind row level security. Nothing about the pages you visit is collected beyond the notes you write.
Repository
JakeLabate/whythoPublic on GitHub
License
MIT.
Can you use it today
Yes. Sign in, install the extension, and press the toolbar button on any page.

Decisions Outlive The People Who Made Them

Recording a decision is the cheap part. Making the decision, and sequencing it against everything else competing for the same engineering time, is the work. That is what an engagement is for.